#ifdef ARCTIC
/**
 @file sys_at_queue_drop.c

 @date 2021-8-13

 @version v1.0

 The file contains AT QoS queue drop APIs of sys layer
*/

/***************************************************************
 *
 * Header Files
 *
 ***************************************************************/
#include "sal.h"
#include "ctc_error.h"
#include "ctc_debug.h"
#include "sys_usw_port_api.h"
#include "sys_usw_common.h"
#include "sys_usw_interrupt.h"
#include "sys_usw_chip.h"
#include "sys_usw_qos.h"
#include "sys_at_qos.h"
#include "drv_api.h"

extern int32
sys_usw_queue_drop_ecn_init(uint8 lchip, uint32 mode);
extern uint32
_sys_usw_queue_drop_wred_hash_make_profile(sys_queue_drop_wred_profile_t* p_prof);
extern bool
_sys_usw_queue_drop_wred_hash_cmp_profile(sys_queue_drop_wred_profile_t* p_prof1,
                                           sys_queue_drop_wred_profile_t* p_prof2);
extern uint32
_sys_usw_queue_drop_wred_free_profileId(sys_queue_drop_wred_profile_t* p_node, uint8* p_lchip);
extern int32
_sys_usw_queue_drop_remove_profile(uint8 lchip, uint8 wred_mode, sys_queue_node_t* p_sys_queue);
extern int32
sys_usw_qos_set_fcdl_detect(uint8 lchip, ctc_qos_resrc_fcdl_detect_t *p_fcdl);
extern int32
sys_usw_qos_get_fcdl_detect(uint8 lchip, ctc_qos_resrc_fcdl_detect_t *p_fcdl);
extern int32
sys_usw_queue_set_obm_pool(uint8 lchip, ctc_qos_obm_resrc_pool_t obm_resrc_pool);
extern int32
sys_usw_queue_get_obm_pool(uint8 lchip, ctc_qos_obm_resrc_pool_t* obm_resrc_pool);
extern int32
sys_usw_port_set_flow_ctl_en(uint8 lchip, void* p_fc_prop, uint8 is_recover);
extern int32
sys_usw_qos_fcdl_get_recover_state(uint8 lchip, uint32 gport, uint8 pri_class, uint8* state);
extern int32
sys_usw_qos_fcdl_timer_en(uint8 lchip, uint8 enable);
extern int32
_sys_usw_qos_fcdl_event_cb(uint8 gchip, void* p_data);
extern int32
sys_at_queue_set_queue_min(uint8 lchip, ctc_qos_resrc_queue_min_t queue_min);
extern int32
sys_at_queue_get_queue_min(uint8 lchip, ctc_qos_resrc_queue_min_t* queue_min);
int32
_sys_at_queue_set_prio_class_drop(uint8 lchip, ctc_qos_drop_t* p_drop);
int32
_sys_at_queue_get_prio_class_drop(uint8 lchip, ctc_qos_drop_t* p_drop);
int32
_sys_at_queue_set_port_drop(uint8 lchip, ctc_qos_drop_t* p_drop);
int32
_sys_at_queue_get_port_drop(uint8 lchip, ctc_qos_drop_t* p_drop);
STATIC int32
_sys_at_queue_drop_get_wred_profile(uint8 lchip, ctc_qos_drop_t* que_drop, sys_queue_node_t* p_sys_queue);

#define __RESRC__
int32
sys_at_queue_set_egs_resrc_guarantee(uint8 lchip, uint8 enable)
{
    ds_t ds;
    uint32 cmd = 0;
    uint32 field_val = 0;
    uint16 index = 0;
    uint8  pp_id = 0;
    uint8  dp_id = 0;
    uint8  dp_chan = 0;
    uint8 loop = 0;
    field_val = enable ? SYS_AT_PORT_MIN_GUARANTEE : 0x3FF;

    for (pp_id = 0; pp_id < SYS_PP_NUM(lchip); pp_id++)
    {
        SYS_QOS_LCHIP_CONVERT(lchip, pp_id);
        for (dp_id = 0; dp_id < MCHIP_CAP(SYS_CAP_DP_MAX_NUM); dp_id++)
        {
            for (dp_chan = 0; dp_chan < MCHIP_CAP(SYS_CAP_PER_DP_CHANNEL_NUM); dp_chan++)
            {
                sys_qos_buffer_info_t* p_buffer_info = NULL;
                uint16 chan_id = 0;
                CTC_ERROR_RETURN(sys_at_get_channel_by_sub_channel(SYS_PP_BASE(lchip)+pp_id, dp_id, dp_chan, &chan_id));
                p_buffer_info = ctc_vector_get(p_usw_queue_master[lchip]->buffer_info_vec, chan_id);

                cmd = DRV_IOR( DsErmPortThrdProfileUc_t, DRV_ENTRY_FLAG);/*dp*/
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, dp_chan, DRV_CMD_DP_EN(cmd, dp_id), &ds));
                SetDsErmPortThrdProfileUc(V, portGuaranteedThrd_f, &ds, field_val);
                cmd = DRV_IOW( DsErmPortThrdProfileUc_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, dp_chan, DRV_CMD_DP_EN(cmd, dp_id), &ds));
                if (p_buffer_info)
                {
                    sal_memcpy(&p_buffer_info->port_thrd_uc, &ds, sizeof(DsErmPortThrdProfileUc_m));
                }

                for(loop = 0; loop < MCHIP_CAP(SYS_CAP_QOS_QUEUE_NUM_PER_CHAN); loop++)
                {
                    index = dp_chan * MCHIP_CAP(SYS_CAP_QOS_QUEUE_NUM_PER_CHAN) + loop;
                    cmd = DRV_IOR( DsErmQueueThrdProfileUc_t, DRV_ENTRY_FLAG);/*dp*/
                    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_DP_EN(cmd, dp_id), &ds));
                    SetDsErmQueueThrdProfileUc(V, queueGuaranteedThrd_f, &ds, field_val);
                    cmd = DRV_IOW( DsErmQueueThrdProfileUc_t, DRV_ENTRY_FLAG);
                    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_DP_EN(cmd, dp_id), &ds));

                    if (p_buffer_info)
                    {
                        sal_memcpy(&p_buffer_info->q_thrd_uc[loop], &ds, sizeof(DsErmQueueThrdProfileUc_m));
                    }
                }

                /*core 0&1*/
                index = SYS_AT_QOS_ENCOD_CORE_CHAN(dp_chan, pp_id, dp_id);
                cmd = DRV_IOR( DsErmPortGuaranteedThrdProfileMc_t, DRV_ENTRY_FLAG);/*core*/
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_PP_EN(cmd), &ds));
                SetDsErmPortGuaranteedThrdProfileMc(V, g_0_portGuaranteedThrd_f, &ds, field_val);
                cmd = DRV_IOW( DsErmPortGuaranteedThrdProfileMc_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_PP_EN(cmd), &ds));
                if (p_buffer_info)
                {
                    sal_memcpy(&p_buffer_info->port_guaranteed_mc, &ds, sizeof(DsErmPortGuaranteedThrdProfileMc_m));
                }

                for(loop = 0; loop < SYS_AT_MC_QUEUE_NUM; loop++)
                {
                    /*core 0&1*/
                    index = SYS_AT_QOS_ENCOD_CORE_QUE_MC(dp_chan, pp_id, dp_id, loop);
                    cmd = DRV_IOR( DsErmQueueGuaranteedThrdProfileMc_t, DRV_ENTRY_FLAG);/*core*/
                    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_PP_EN(cmd), &ds));
                    SetDsErmQueueGuaranteedThrdProfileMc(V, g_0_queueGuaranteedThrd_f, &ds, field_val);
                    cmd = DRV_IOW( DsErmQueueGuaranteedThrdProfileMc_t, DRV_ENTRY_FLAG);
                    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_PP_EN(cmd), &ds));

                    if (p_buffer_info)
                    {
                        sal_memcpy(&p_buffer_info->q_guaranteed_mc[loop], &ds, sizeof(DsErmQueueGuaranteedThrdProfileMc_m));
                    }
                }
            }
       }
    }
    return CTC_E_NONE;
}

/*
used for cross core table
cur_pp_id: means the current PORT or queue in which pp
query_pp_id: means query which pp's index with from pp view
return table shift value
*/
uint32
sys_at_qos_get_corss_core_tbl_idx(uint8 lchip, uint8 cur_pp_id, uint8 query_pp_id, uint32 shift)
{
    if (cur_pp_id >= PP_NUM_PER_CORE && query_pp_id >= PP_NUM_PER_CORE)
    {
        /*keep index, cross core self count */
        return 0;
    }
    else if (cur_pp_id >= PP_NUM_PER_CORE || query_pp_id >= PP_NUM_PER_CORE)
    {
        return shift;
    }
    return 0;
}
uint32
sys_at_qos_get_corss_core_lchip(uint8* lchip_tmp, uint8 cur_pp_id, uint8 query_pp_id)
{
    uint8 lchip = *lchip_tmp;
    if (query_pp_id >= PP_NUM_PER_CORE && cur_pp_id < PP_NUM_PER_CORE)
    {
        SYS_QOS_LCHIP_CONVERT(*lchip_tmp, cur_pp_id + PP_NUM_PER_CORE);
    }
    else if (query_pp_id < PP_NUM_PER_CORE && cur_pp_id >= PP_NUM_PER_CORE)
    {
        SYS_QOS_LCHIP_CONVERT(*lchip_tmp, cur_pp_id - PP_NUM_PER_CORE);
    }
    else
    {
        SYS_QOS_LCHIP_CONVERT(*lchip_tmp, cur_pp_id);
    }
    return CTC_E_NONE;
}

int32
sys_at_resrc_query_pool_stats(uint8 lchip, void* p_sys_stats)
{
    uint32 cmd = 0;
    uint32 index = 0;
    uint32 tbl_id = 0;
    sys_port_info_t port_info;
    sys_queue_node_t* p_queue_node = NULL;
    ctc_qos_resrc_pool_stats_t* p_stats = (ctc_qos_resrc_pool_stats_t* )p_sys_stats;
    ds_t ds;
    uint16 lport = 0;
    uint16 queue_id = 0;
    uint8 irm_snapshot_en = 0;
    uint8 erm_snapshot_en = 0;
    uint8 ofst = 0;

    CTC_MAX_VALUE_CHECK(p_stats->pp_id, SYS_PP_NUM(lchip) - 1);
    SYS_QOS_LCHIP_CONVERT(lchip, (p_stats->pp_id >= PP_NUM_PER_CORE) ? PP_NUM_PER_CORE : 0);
    cmd = DRV_IOR(IrmResrcMonState_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ds));
    irm_snapshot_en = GetIrmResrcMonState(V, resrcShadowLock_f, &ds);

    cmd = DRV_IOR(ErmResrcMonState_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ds));
    erm_snapshot_en = GetErmResrcMonState(V, resrcShadowLock_f, &ds);

    switch (p_stats->type)
    {
    case CTC_QOS_RESRC_STATS_IGS_POOL_COUNT:
        if(irm_snapshot_en && !p_stats->non_uc)
        {
            if (CTC_QOS_IGS_RESRC_SC3_POOL >= p_stats->pool)
            {
                cmd = DRV_IOR(DsIrmScCntUcShadow_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ds));
                p_stats->count = GetDsIrmScCntUcShadow(V, g_0_scCnt_f + p_stats->pool , &ds);
            }
            else if (CTC_QOS_IGS_RESRC_C2C_POOL == p_stats->pool)
            {
                cmd = DRV_IOR(DsIrmMiscCntUcShadow_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ds));
                p_stats->count = GetDsIrmMiscCntUcShadow(V, c2cCnt_f, &ds);
            }
            else if (CTC_QOS_IGS_RESRC_CONTROL_POOL == p_stats->pool)
            {
                cmd = DRV_IOR(DsIrmMiscCntUcShadow_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ds));
                p_stats->count = GetDsIrmMiscCntUcShadow(V, criticalCnt_f, &ds);
            }
            else if (CTC_QOS_IGS_RESRC_ROUND_TRIP_POOL == p_stats->pool)
            {
                cmd = DRV_IOR( DsIrmHeadroomCntShadow_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ds));
                p_stats->count = GetDsIrmHeadroomCntShadow(V, headroomCnt_f, &ds);
            }
        }
        else
        {
            if (CTC_QOS_IGS_RESRC_SC3_POOL >= p_stats->pool)
            {
                tbl_id = p_stats->non_uc ? DsIrmScCntMc_t : DsIrmScCntUc_t;
                cmd = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ds));
                p_stats->count = p_stats->non_uc ? GetDsIrmScCntMc(V, g_0_scCnt_f + p_stats->pool, &ds)
                                                 : GetDsIrmScCntUc(V, g_0_scCnt_f + p_stats->pool, &ds);
            }
            else if (CTC_QOS_IGS_RESRC_C2C_POOL == p_stats->pool)
            {
                tbl_id = p_stats->non_uc ? DsIrmMiscCntMc_t : DsIrmMiscCntUc_t;
                cmd = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ds));
                p_stats->count = p_stats->non_uc ? GetDsIrmMiscCntMc(V, c2cCnt_f, &ds)
                                                 : GetDsIrmMiscCntUc(V, c2cCnt_f, &ds);
            }
            else if (CTC_QOS_IGS_RESRC_CONTROL_POOL == p_stats->pool)
            {
                tbl_id = p_stats->non_uc ? DsIrmMiscCntMc_t : DsIrmMiscCntUc_t;
                cmd = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ds));
                p_stats->count = p_stats->non_uc ? GetDsIrmMiscCntMc(V, criticalCnt_f, &ds)
                                                 : GetDsIrmMiscCntUc(V, criticalCnt_f, &ds);
            }
            else if (CTC_QOS_IGS_RESRC_ROUND_TRIP_POOL == p_stats->pool && !p_stats->non_uc)
            {
                cmd = DRV_IOR( DsIrmHeadroomCnt_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ds));
                p_stats->count = GetDsIrmHeadroomCnt(V, headroomCnt_f, &ds);
            }
        }
        break;

    case CTC_QOS_RESRC_STATS_IGS_TOTAL_COUNT:
        if(irm_snapshot_en && !p_stats->non_uc)
        {
            cmd = DRV_IOR(DsIrmMiscCntUcShadow_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ds));
            p_stats->count = GetDsIrmMiscCntUcShadow(V, totalCnt_f, &ds);
        }
        else
        {
            tbl_id = p_stats->non_uc ? DsIrmMiscCntMc_t : DsIrmMiscCntUc_t;
            cmd = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ds));
            p_stats->count = p_stats->non_uc ? GetDsIrmMiscCntMc(V, totalCnt_f, &ds)
                                             : GetDsIrmMiscCntUc(V, totalCnt_f, &ds);

        }

        break;

    case CTC_QOS_RESRC_STATS_EGS_POOL_COUNT:
        if (erm_snapshot_en && !p_stats->non_uc)
        {
            if (CTC_QOS_EGS_RESRC_SC3_POOL >= p_stats->pool)
            {
                cmd = DRV_IOR(DsErmScCntUcShadow_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ds));
                p_stats->count = GetDsErmScCntUcShadow(V, g_0_scCnt_f + p_stats->pool , &ds);
            }
        }
        else
        {
            if(CTC_QOS_EGS_RESRC_SC3_POOL >= p_stats->pool)
            {
                tbl_id = p_stats->non_uc ? DsErmScCntMc_t : DsErmScCntUc_t;
                cmd = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ds));
                p_stats->count = p_stats->non_uc ? GetDsErmScCntMc(V, g_0_scCnt_f + p_stats->pool, &ds)
                                                 : GetDsErmScCntUc(V, g_0_scCnt_f + p_stats->pool, &ds);
            }
        }
        break;

    case CTC_QOS_RESRC_STATS_EGS_TOTAL_COUNT:
        if(erm_snapshot_en && !p_stats->non_uc)
        {
            cmd = DRV_IOR(DsErmMiscCntUcShadow_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ds));
            p_stats->count = GetDsErmMiscCntUcShadow(V, totalCnt_f, &ds);
        }
        else
        {
            tbl_id = p_stats->non_uc ? DsErmMiscCntMc_t : DsErmMiscCntUc_t;
            cmd = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ds));
            p_stats->count = p_stats->non_uc ? GetDsErmMiscCntMc(V, g_0_totalCnt_f, &ds)
                                             : GetDsErmMiscCntUc(V, totalCnt_f, &ds);

        }
        break;

    case CTC_QOS_RESRC_STATS_QUEUE_COUNT:
        CTC_MAX_VALUE_CHECK(p_stats->queue.class_prio, SYS_QUEUE_SUB_NODE_NUM-1);

        CTC_ERROR_RETURN(sys_at_queue_get_queue_id(lchip, &p_stats->queue, &queue_id));
        p_queue_node = ctc_vector_get(p_usw_queue_master[lchip]->queue_vec, queue_id);
        if (NULL == p_queue_node)
        {
            SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Entry not exist \n");
            return CTC_E_NOT_EXIST;
        }

        ofst = SYS_AT_COS_SUB_NODE_OFST(p_queue_node, p_stats->queue.class_prio);
        if (erm_snapshot_en && SYS_QUE_OFST_UC == p_queue_node->node[ofst].type)
        {
            if (SYS_QUEUE_TYPE_NORMAL == p_queue_node->type || SYS_QUEUE_TYPE_EUNIT == p_queue_node->type)
            {
                SYS_QOS_LCHIP_CONVERT(lchip, p_queue_node->pp_id);
                index = SYS_AT_QOS_ENCOD_DP_QUE_UC(p_queue_node->sub_chan, p_queue_node->node[ofst].ofst);
                cmd = DRV_IOR(DsErmQueueCntUcShadow_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_DP_EN(cmd, p_queue_node->dp_id), &ds));
                p_stats->count = GetDsErmQueueCntUcShadow(V, queueCnt_f, &ds);
            }
            else if (SYS_QUEUE_TYPE_EXCP_UC == p_queue_node->type)
            {
                cmd = DRV_IOR(DsErmDmaCntUcShadow_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_queue_node->offset, DRV_CMD_DP_EN(cmd, p_queue_node->dp_id), &ds));
                p_stats->count = GetDsErmDmaCntUcShadow(V, queueCnt_f, &ds);
            }
        }
        else
        {
            uint8 q_ofst_type = p_queue_node->node[ofst].type;
            uint8 q_ofst =p_queue_node->node[ofst].ofst;
            if(SYS_QUE_OFST_MC == q_ofst_type)
            {
                if (SYS_QUEUE_TYPE_NORMAL == p_queue_node->type || SYS_QUEUE_TYPE_EUNIT == p_queue_node->type)
                {
                    index = SYS_AT_QOS_ENCOD_CORE_QUE_MC(p_queue_node->sub_chan, p_queue_node->pp_id, p_queue_node->dp_id, q_ofst);
                    SYS_QOS_LCHIP_CONVERT(lchip, p_queue_node->pp_id);
                    cmd = DRV_IOR(DsErmQueueCntMc_t, DRV_ENTRY_FLAG);
                    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_PP_EN(cmd), &ds));
                    p_stats->count = GetDsErmQueueCntMc(V, g_0_queueCnt_f, &ds);
                }
                else if (SYS_QUEUE_TYPE_EXCP == p_queue_node->type)
                {
                    cmd = DRV_IOR(DsErmDmaCntMc_t, DRV_ENTRY_FLAG);
                    CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_queue_node->offset, DRV_CMD_PP_EN(cmd), &ds));
                    p_stats->count = GetDsErmDmaCntMc(V, g_0_queueCnt_f, &ds);
                }
            }
            else if(SYS_QUE_OFST_UC == q_ofst_type)
            {
                if (SYS_QUEUE_TYPE_NORMAL == p_queue_node->type || SYS_QUEUE_TYPE_EUNIT == p_queue_node->type)
                {
                    index = SYS_AT_QOS_ENCOD_DP_QUE_UC(p_queue_node->sub_chan, q_ofst);
                    /*convert cross core pp*/
                    CTC_ERROR_RETURN(sys_at_qos_get_corss_core_lchip(&lchip, p_queue_node->pp_id, p_stats->pp_id));
                    index += sys_at_qos_get_corss_core_tbl_idx(lchip, p_queue_node->pp_id, p_stats->pp_id, DRV_INS(1, 0));
                    cmd = DRV_IOR(DsErmQueueCntUc_t, DRV_ENTRY_FLAG);
                    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_DP_EN(cmd, p_queue_node->dp_id), &ds));
                    p_stats->count = GetDsErmQueueCntUc(V, queueCnt_f, &ds);
                }
                else if (SYS_QUEUE_TYPE_EXCP_UC == p_queue_node->type)
                {
                    index = p_queue_node->offset;
                    index += sys_at_qos_get_corss_core_tbl_idx(lchip, 0, p_stats->pp_id, DRV_INS(1, 0));
                    cmd = DRV_IOR(DsErmDmaCntUc_t, DRV_ENTRY_FLAG);
                    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_PP_EN(cmd), &ds));
                    p_stats->count = GetDsErmDmaCntUc(V, queueCnt_f, &ds);
                }
            }
        }
        break;
    case CTC_QOS_RESRC_STATS_IGS_PORT_COUNT:
        SYS_MAP_CTC_GPORT_TO_DRV_LPORT_WITH_CHECK(p_stats->gport, lchip, lport);
        if (!SYS_GPORT_IS_NETWORK_PORT(p_stats->gport))
        {
            SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Invalid localphy port \n");
            return CTC_E_INVALID_PORT;
        }
        CTC_ERROR_RETURN(sys_usw_port_api_get_com_info(lchip, lport, CTC_MAP_GPORT_TO_MCHAN_IDX(p_stats->gport), &port_info));
        SYS_QOS_LCHIP_CONVERT(lchip, port_info.pp_id);
        if (irm_snapshot_en && !p_stats->non_uc)
        {
            cmd = DRV_IOR(DsIrmPortCntUcShadow_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, port_info.sub_chan_id, DRV_CMD_DP_EN(cmd, port_info.dp_id), &ds));
            p_stats->count = GetDsIrmPortCntUcShadow(V, portCnt_f, &ds);
        }
        else
        {
            tbl_id = p_stats->non_uc ? DsIrmPortCntMc_t : DsIrmPortCntUc_t;
            cmd = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, port_info.sub_chan_id, DRV_CMD_DP_EN(cmd, port_info.dp_id), &ds));
            p_stats->count = p_stats->non_uc ? GetDsIrmPortCntMc(V, portCnt_f, &ds)
                                             : GetDsIrmPortCntUc(V, portCnt_f, &ds);

        }
        break;

    case CTC_QOS_RESRC_STATS_EGS_PORT_COUNT:
        SYS_MAP_CTC_GPORT_TO_DRV_LPORT_WITH_CHECK(p_stats->gport, lchip, lport);
        if (!SYS_GPORT_IS_NETWORK_PORT(p_stats->gport))
        {
            SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Invalid localphy port \n");
            return CTC_E_INVALID_PORT;
        }
        CTC_ERROR_RETURN(sys_usw_port_api_get_com_info(lchip, lport, CTC_MAP_GPORT_TO_MCHAN_IDX(p_stats->gport), &port_info));

        /*convert cross core pp*/
        CTC_ERROR_RETURN(sys_at_qos_get_corss_core_lchip(&lchip, port_info.pp_id, p_stats->pp_id));
        if (p_stats->non_uc)
        {
            index = SYS_AT_QOS_ENCOD_CORE_CHAN(port_info.sub_chan_id, port_info.pp_id, port_info.dp_id);
            index += sys_at_qos_get_corss_core_tbl_idx(lchip, port_info.pp_id, p_stats->pp_id, DRV_TABLE_MAX_INDEX(lchip, DsErmPortCntMc_t) / 2);
            cmd = DRV_IOR(DsErmPortCntMc_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_PP_EN(cmd), &ds));
            p_stats->count = GetDsErmPortCntMc(V, g_0_portCnt_f, &ds);
        }
        else
        {
            index = port_info.sub_chan_id;
            index += sys_at_qos_get_corss_core_tbl_idx(lchip, port_info.pp_id, p_stats->pp_id, DRV_INS(1, 0));
            if (erm_snapshot_en)
            {
                cmd = DRV_IOR(DsErmPortCntUcShadow_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_DP_EN(cmd, port_info.dp_id), &ds));
                p_stats->count = GetDsErmPortCntUcShadow(V, portCnt_f, &ds);
            }
            else
            {
                cmd = DRV_IOR(DsErmPortCntUc_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_DP_EN(cmd, port_info.dp_id), &ds));
                p_stats->count = GetDsErmPortCntUc(V, portCnt_f, &ds);
            }
        }
        break;
    case CTC_QOS_RESRC_STATS_PRI_CLASS_COUNT:
        CTC_MAX_VALUE_CHECK(p_stats->pri_class, 7);
        SYS_MAP_CTC_GPORT_TO_DRV_LPORT_WITH_CHECK(p_stats->gport, lchip, lport);
        if (!SYS_GPORT_IS_NETWORK_PORT(p_stats->gport))
        {
            SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Invalid localphy port \n");
            return CTC_E_INVALID_PORT;
        }
        CTC_ERROR_RETURN(sys_usw_port_api_get_com_info(lchip, lport, CTC_MAP_GPORT_TO_MCHAN_IDX(p_stats->gport), &port_info));
        SYS_QOS_LCHIP_CONVERT(lchip, port_info.pp_id);

        if (erm_snapshot_en && !p_stats->non_uc)
        {
            cmd = DRV_IOR(DsIrmPortTcCntUcShadow_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, (port_info.sub_chan_id << 3 | p_stats->pri_class), DRV_CMD_DP_EN(cmd, port_info.dp_id), &ds));
            p_stats->count = GetDsIrmPortTcCntUcShadow(V, portTcCnt_f, &ds);
        }
        else
        {
            if (p_stats->non_uc)
            {
                cmd = DRV_IOR(DsIrmPortTcCntMc_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, (port_info.sub_chan_id << 3 | p_stats->pri_class), DRV_CMD_DP_EN(cmd, port_info.dp_id), &ds));
                p_stats->count = GetDsIrmPortTcCntMc(V, portTcCnt_f, &ds);
            }
            else
            {
                cmd = DRV_IOR(DsIrmPortTcCntUc_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, (port_info.sub_chan_id << 3 | p_stats->pri_class), DRV_CMD_DP_EN(cmd, port_info.dp_id), &ds));
                p_stats->count = GetDsIrmPortTcCntUc(V, portTcCnt_f, &ds);
            }
        }
        break;
    case CTC_QOS_RESRC_STATS_IGS_PORT_SC_COUNT:
        SYS_MAP_CTC_GPORT_TO_DRV_LPORT_WITH_CHECK(p_stats->gport, lchip, lport);
        if (!SYS_GPORT_IS_NETWORK_PORT(p_stats->gport))
        {
            SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Invalid localphy port \n");
            return CTC_E_INVALID_PORT;
        }
        CTC_ERROR_RETURN(sys_usw_port_api_get_com_info(lchip, lport, CTC_MAP_GPORT_TO_MCHAN_IDX(p_stats->gport), &port_info));
        CTC_MAX_VALUE_CHECK(p_stats->pool, CTC_QOS_IGS_RESRC_SC3_POOL);
        SYS_QOS_LCHIP_CONVERT(lchip, port_info.pp_id);
        if (irm_snapshot_en && !p_stats->non_uc)
        {
            cmd = DRV_IOR(DsErmPortScCntUcShadow_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, port_info.sub_chan_id << 2 | p_stats->pool, DRV_CMD_DP_EN(cmd, port_info.dp_id), &ds));
            p_stats->count = GetDsIrmPortScCntUcShadow(V, portScCnt_f, &ds);
        }
        else
        {
            tbl_id = p_stats->non_uc ? DsIrmPortScCntMc_t : DsIrmPortScCntUc_t;
            cmd = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, port_info.sub_chan_id << 2 | p_stats->pool, DRV_CMD_DP_EN(cmd, port_info.dp_id), &ds));
            p_stats->count = p_stats->non_uc ? GetDsIrmPortScCntMc(V, portScCnt_f, &ds)
                                             : GetDsIrmPortScCntUc(V, portScCnt_f, &ds);

        }
        break;
    case CTC_QOS_RESRC_STATS_EGS_PORT_SC_COUNT:
        SYS_MAP_CTC_GPORT_TO_DRV_LPORT_WITH_CHECK(p_stats->gport, lchip, lport);
        if (!SYS_GPORT_IS_NETWORK_PORT(p_stats->gport))
        {
            SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Invalid localphy port \n");
            return CTC_E_INVALID_PORT;
        }
        CTC_ERROR_RETURN(sys_usw_port_api_get_com_info(lchip, lport, CTC_MAP_GPORT_TO_MCHAN_IDX(p_stats->gport), &port_info));
        CTC_MAX_VALUE_CHECK(p_stats->pool, CTC_QOS_EGS_RESRC_SC3_POOL);
        /*convert cross core pp*/
        CTC_ERROR_RETURN(sys_at_qos_get_corss_core_lchip(&lchip, port_info.pp_id, p_stats->pp_id));
        if (p_stats->non_uc)
        {
            index = SYS_AT_QOS_ENCOD_CORE_CHAN(port_info.sub_chan_id, port_info.pp_id, port_info.dp_id) << 2 | p_stats->pool;
            index += sys_at_qos_get_corss_core_tbl_idx(lchip, port_info.pp_id, p_stats->pp_id, DRV_TABLE_MAX_INDEX(lchip, DsErmPortScCntMc_t) / 2);
            cmd = DRV_IOR(DsErmPortCntMc_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_PP_EN(cmd), &ds));
            p_stats->count = GetDsErmPortScCntMc(V, g_0_portScCnt_f, &ds);
        }
        else
        {
            index = port_info.sub_chan_id << 2 | p_stats->pool;
            index += sys_at_qos_get_corss_core_tbl_idx(lchip, port_info.pp_id, p_stats->pp_id, DRV_INS(1, 0));
            if (erm_snapshot_en)
            {
                cmd = DRV_IOR(DsErmPortScCntUcShadow_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_DP_EN(cmd, port_info.dp_id), &ds));
                p_stats->count = GetDsErmPortScCntUcShadow(V, portScCnt_f, &ds);
            }
            else
            {
                cmd = DRV_IOR(DsErmPortScCntUc_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_DP_EN(cmd, port_info.dp_id), &ds));
                p_stats->count = GetDsErmPortScCntUc(V, portScCnt_f, &ds);
            }
        }
        break;
    default:
        return CTC_E_INVALID_PARAM;
    }

    return CTC_E_NONE;
}


int32
sys_at_resrc_fc_set_profile(uint8 lchip, uint16 chan_id, void* p_resrc_fc)
{
    uint32 cmd = 0;
    uint32 sub_chan = 0;
    uint32 step = 0;
    uint8 loop = 0;
    uint32 pp_id = 0;
    uint32 dp_id = 0;
    uint16 lport = 0;
    ctc_qos_drop_t drop;
    ctc_qos_resrc_fc_t *p_fc = (ctc_qos_resrc_fc_t *)p_resrc_fc;
    sys_port_info_t port_info = {0};

    CTC_PTR_VALID_CHECK(p_fc);

    SYS_MAP_CTC_GPORT_TO_DRV_LPORT_WITH_CHECK(p_fc->gport, lchip, lport);
    CTC_ERROR_RETURN(sys_usw_port_api_get_com_info(lchip, lport, 0, &port_info));
    if (!(SYS_DMPS_NETWORK_PORT == port_info.port_type || SYS_DMPS_CPUMAC_NETWORK_PORT == port_info.port_type || SYS_DMPS_CPU_MAC_PORT == port_info.port_type))
    {
        return CTC_E_INVALID_PARAM;
    }
    sub_chan = port_info.sub_chan_id;
    pp_id = port_info.pp_id;
    dp_id = port_info.dp_id;

    SYS_QOS_LCHIP_CONVERT(lchip, pp_id);
    {
        sys_qos_fc_profile_t fc_profile;
        DsIrmPortFlowControlThrdProfile_m irm_thrd_profile;
        uint32 xoff_thrd = 0;
        uint32 xon_thrd = 0;
        sal_memset(&fc_profile, 0, sizeof(fc_profile));
        cmd = DRV_IOR(DsIrmPortFlowControlThrdProfile_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, sub_chan, DRV_CMD_DP_EN(cmd, dp_id), &irm_thrd_profile));
        if (p_fc->is_pfc)
        {
            step = DsIrmPortFlowControlThrdProfile_g_1_xoffThrd_f - DsIrmPortFlowControlThrdProfile_g_0_xoffThrd_f;
            xoff_thrd = GetDsIrmPortFlowControlThrdProfile(V, g_0_xoffThrd_f + p_fc->priority_class*step, &irm_thrd_profile);
            xon_thrd = GetDsIrmPortFlowControlThrdProfile(V, g_0_xonThrd_f + p_fc->priority_class*step, &irm_thrd_profile);
            if (0x3FFFF != xoff_thrd || 0x3FFFF != xon_thrd)
            {
                SetDsIrmPortFlowControlThrdProfile(V, g_0_xoffThrd_f + p_fc->priority_class*step, &irm_thrd_profile, p_fc->xoff_thrd);
                SetDsIrmPortFlowControlThrdProfile(V, g_0_xonThrd_f + p_fc->priority_class*step, &irm_thrd_profile, p_fc->xon_thrd);
                cmd = DRV_IOW(DsIrmPortFlowControlThrdProfile_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, sub_chan, DRV_CMD_DP_EN(cmd, dp_id), &irm_thrd_profile));
            }
        }
        else
        {
            SetDsIrmPortFlowControlThrdProfile(V, g_0_xoffThrd_f, &irm_thrd_profile, p_fc->xoff_thrd);
            SetDsIrmPortFlowControlThrdProfile(V, g_0_xonThrd_f, &irm_thrd_profile, p_fc->xon_thrd);
            cmd = DRV_IOW(DsIrmPortFlowControlThrdProfile_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, sub_chan, DRV_CMD_DP_EN(cmd, dp_id), &irm_thrd_profile));
        }

        fc_profile.xon = p_fc->xon_thrd;
        fc_profile.xoff = p_fc->xoff_thrd;
        if (p_fc->is_pfc)
        {
            if (!(p_usw_queue_master[lchip]->p_pfc_profile[chan_id][p_fc->priority_class]))
            {
                p_usw_queue_master[lchip]->p_pfc_profile[chan_id][p_fc->priority_class] = mem_malloc(MEM_QUEUE_MODULE, sizeof(sys_qos_fc_profile_t));
                if(NULL == p_usw_queue_master[lchip]->p_pfc_profile[chan_id][p_fc->priority_class])
                {
                    return CTC_E_NO_MEMORY;
                }
            }
            sal_memcpy(p_usw_queue_master[lchip]->p_pfc_profile[chan_id][p_fc->priority_class], &fc_profile, sizeof(sys_qos_fc_profile_t));
            SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_PFC_PROFILE, 1);
        }
        else
        {
            if (!(p_usw_queue_master[lchip]->p_fc_profile[chan_id]))
            {
                p_usw_queue_master[lchip]->p_fc_profile[chan_id] = mem_malloc(MEM_QUEUE_MODULE, sizeof(sys_qos_fc_profile_t));
                if(NULL == p_usw_queue_master[lchip]->p_fc_profile[chan_id])
                {
                    return CTC_E_NO_MEMORY;
                }
            }
            sal_memcpy(p_usw_queue_master[lchip]->p_fc_profile[chan_id], &fc_profile, sizeof(sys_qos_fc_profile_t));
            SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_FC_PROFILE, 1);
        }
    }

    /*Set Drop Profile*/
    sal_memset(&drop, 0, sizeof(drop));
    drop.dir = CTC_INGRESS;
    drop.gport = CTC_MAP_LPORT_TO_GPORT(CTC_MAP_GPORT_TO_GCHIP(p_fc->gport), lport);
    for(loop = 0; loop < 4; loop++)
    {
        drop.drop.max_th[loop] = p_fc->drop_thrd;
    }
    if(p_fc->is_pfc)
    {
        drop.type = CTC_QOS_BUFFER_PORT_PRIO_CLASS;
        drop.prio_class = p_fc->priority_class;
        CTC_ERROR_RETURN(_sys_at_queue_set_prio_class_drop(lchip, &drop));
    }
    else
    {
        drop.type = CTC_QOS_BUFFER_PORT;
        CTC_ERROR_RETURN(_sys_at_queue_set_port_drop(lchip, &drop));
    }

    return CTC_E_NONE;
}

int32
sys_at_resrc_fc_get_profile(uint8 lchip, uint16 chan_id, void* p_resrc_fc)
{
    uint32 sub_chan = 0;
    uint16 index = 0;
    uint32 cmd = 0;
    uint32 value = 0;
    uint32 pp_id = 0;
    uint32 dp_id = 0;
    uint16 lport = 0;
    ctc_qos_resrc_fc_t *p_fc = (ctc_qos_resrc_fc_t *)p_resrc_fc;
    ds_t ds;
    sys_port_info_t port_info = {0};

    CTC_PTR_VALID_CHECK(p_fc);
    
    SYS_MAP_CTC_GPORT_TO_DRV_LPORT_WITH_CHECK(p_fc->gport, lchip, lport);
    CTC_ERROR_RETURN(sys_usw_port_api_get_com_info(lchip, lport, 0, &port_info));
    if (!(SYS_DMPS_NETWORK_PORT == port_info.port_type || SYS_DMPS_CPUMAC_NETWORK_PORT == port_info.port_type || SYS_DMPS_CPU_MAC_PORT == port_info.port_type))
    {
        return CTC_E_INVALID_PARAM;
    }
    sub_chan = port_info.sub_chan_id;
    pp_id = port_info.pp_id;
    dp_id = port_info.dp_id;
    SYS_QOS_LCHIP_CONVERT(lchip, pp_id);

    {
        /*Normal flow Control*/
        if (p_fc->is_pfc && p_usw_queue_master[lchip]->p_pfc_profile[chan_id][p_fc->priority_class])
        {
            p_fc->xon_thrd = p_usw_queue_master[lchip]->p_pfc_profile[chan_id][p_fc->priority_class]->xon;
            p_fc->xoff_thrd = p_usw_queue_master[lchip]->p_pfc_profile[chan_id][p_fc->priority_class]->xoff;
        }
        else if (!p_fc->is_pfc && p_usw_queue_master[lchip]->p_fc_profile[chan_id])
        {
            p_fc->xon_thrd = p_usw_queue_master[lchip]->p_fc_profile[chan_id]->xon;
            p_fc->xoff_thrd = p_usw_queue_master[lchip]->p_fc_profile[chan_id]->xoff;
        }
        else
        {
            p_fc->xon_thrd = 0x380;
            p_fc->xoff_thrd = 0x400;
        }

        if (p_fc->is_pfc)
        {
            index = sub_chan << 3 | p_fc->priority_class;
            cmd = DRV_IOR(DsIrmPortTcLimitedThrdProfileUc_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_DP_EN(cmd, dp_id), &ds));
            value = GetDsIrmPortTcLimitedThrdProfileUc(V, g_0_portTcLimitedThrd_f, &ds);
        }
        else
        {
            cmd = DRV_IOR(DsIrmPortLimitedThrdProfileUc_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, sub_chan, DRV_CMD_DP_EN(cmd, dp_id), &ds));
            value = GetDsIrmPortLimitedThrdProfileUc(V, g_0_portLimitedThrd_f, &ds);
        }

        p_fc->drop_thrd = ((value * 8) > MCHIP_CAP(SYS_CAP_QOS_DROP_TOTAL_UC_POOL_SIZE)) ? MCHIP_CAP(SYS_CAP_QOS_DROP_TOTAL_UC_POOL_SIZE) : (value * 8);
    }

    return CTC_E_NONE;
}

int32
sys_at_resrc_get_que_drop(uint8 lchip, void* p_que_node, void* p_sys_drop, uint8 wred_mode,  uint8* wtd_en, uint8* wred_en)
{

    uint32 cmd = 0;
    uint32 field_val = 0;
    uint32 index = 0;
    uint8 drop_factor[16] = {7,8,9,10,0,0,0,0,0,6,5,4,3,2,1,0};
    uint8 is_dynamic = 0;
    uint8 wtd = 0;
    sys_queue_node_t* p_queue_node = (sys_queue_node_t*)p_que_node;
    ctc_qos_drop_t* p_drop = (ctc_qos_drop_t*)p_sys_drop;
    ds_t  ds;
    uint8 q_ofst_type = 0;
    uint8 q_ofst = 0;
    uint8 ofst = 0;

    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    CTC_PTR_VALID_CHECK(p_drop);
    sal_memset(ds, 0, sizeof(ds));
    SYS_QOS_LCHIP_CONVERT(lchip, p_queue_node->pp_id);

    ofst = SYS_AT_COS_SUB_NODE_OFST(p_queue_node, p_drop->queue.class_prio);
    if (SYS_QUEUE_TYPE_NORMAL == p_queue_node->type || SYS_QUEUE_TYPE_EUNIT == p_queue_node->type)
    {
        q_ofst_type = p_queue_node->node[ofst].type;
        q_ofst = p_queue_node->node[ofst].ofst;

        if(SYS_QUE_OFST_UC == q_ofst_type)
        {
            CTC_MAX_VALUE_CHECK(q_ofst, SYS_AT_UC_QUEUE_NUM - 1);
            index = SYS_AT_QOS_ENCOD_DP_QUE_UC(p_queue_node->sub_chan, q_ofst);
            cmd = DRV_IOR(DsErmQueueThrdProfileUc_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_DP_EN(cmd, p_queue_node->dp_id), &ds));
            is_dynamic = GetDsErmQueueThrdProfileUc(V, g_0_queueLimitedAutoEn_f, &ds);
            field_val = GetDsErmQueueThrdProfileUc(V, g_0_queueLimitedThrd_f, &ds);
            wtd = (is_dynamic || field_val != SYS_AT_LIMIT_MAX_THRD_UC);
        }
        else if(SYS_QUE_OFST_MC == q_ofst_type)
        {
            CTC_MAX_VALUE_CHECK(q_ofst, SYS_AT_MC_QUEUE_NUM - 1);
            index = SYS_AT_QOS_ENCOD_CORE_QUE_MC(p_queue_node->sub_chan, p_queue_node->pp_id, p_queue_node->dp_id, q_ofst);
            cmd = DRV_IOR(DsErmQueueLimitedThrdProfileMc_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_PP_EN(cmd), &ds));
            is_dynamic = GetDsErmQueueLimitedThrdProfileMc(V, g_0_queueLimitedAutoEn_f, &ds);
            field_val = GetDsErmQueueLimitedThrdProfileMc(V, g_0_queueLimitedThrd_f, &ds);
            wtd = (is_dynamic || field_val != SYS_AT_LIMIT_MAX_THRD_MC);
        }
    }
    else if (SYS_QUEUE_TYPE_EXCP == p_queue_node->type)
    {
        cmd = DRV_IOR(DsErmDmaLimitedThrdProfileMc_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_queue_node->offset, DRV_CMD_PP_EN(cmd), &ds));
        is_dynamic = GetDsErmDmaLimitedThrdProfileMc(V, g_0_queueLimitedAutoEn_f, &ds);
        field_val = GetDsErmDmaLimitedThrdProfileMc(V, g_0_queueLimitedThrd_f, &ds);
        wtd = (is_dynamic || field_val != SYS_AT_LIMIT_MAX_THRD_MC);
    }
    else if (SYS_QUEUE_TYPE_EXCP_UC == p_queue_node->type)
    {
        cmd = DRV_IOR(DsErmDmaThrdProfileUc_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_queue_node->offset, DRV_CMD_PP_EN(cmd), &ds));
        is_dynamic = GetDsErmDmaThrdProfileUc(V, g_0_queueLimitedAutoEn_f, &ds);
        field_val = GetDsErmDmaThrdProfileUc(V, g_0_queueLimitedThrd_f, &ds);
        wtd = (is_dynamic || field_val != SYS_AT_LIMIT_MAX_THRD_UC);
    }

    p_drop->drop.is_coexist = p_queue_node->node[ofst].drop_wred_profile_id && wtd;

    if(wred_mode)
    {
        if (wred_en)
        {
            *wred_en = p_queue_node->node[ofst].drop_wred_profile_id ? 1 : 0;
        }
        return _sys_at_queue_drop_get_wred_profile(lchip, p_drop, p_que_node);
    }
    else
    {
        if (wtd_en)
        {
            *wtd_en = wtd ? 1 : 0;
        }
        if (SYS_QUEUE_TYPE_EXCP == p_queue_node->type)
        {
            if (is_dynamic == 0)
            {
                p_drop->drop.max_th[0] = GetDsErmDmaLimitedThrdProfileMc(V, g_0_queueLimitedThrd_f, &ds) * 8;
                p_drop->drop.max_th[1] = GetDsErmDmaLimitedThrdProfileMc(V, g_1_queueLimitedThrd_f, &ds) * 8;
                p_drop->drop.max_th[2] = GetDsErmDmaLimitedThrdProfileMc(V, g_2_queueLimitedThrd_f, &ds) * 8;
                p_drop->drop.max_th[3] = GetDsErmDmaLimitedThrdProfileMc(V, g_3_queueLimitedThrd_f, &ds) * 8;
            }
            else if (is_dynamic == 1)
            {
                p_drop->drop.drop_factor[0] = drop_factor[GetDsErmDmaLimitedThrdProfileMc(V, g_0_queueLimitedFactor_f, &ds)];
                p_drop->drop.drop_factor[1] = drop_factor[GetDsErmDmaLimitedThrdProfileMc(V, g_1_queueLimitedFactor_f, &ds)];
                p_drop->drop.drop_factor[2] = drop_factor[GetDsErmDmaLimitedThrdProfileMc(V, g_2_queueLimitedFactor_f, &ds)];
                p_drop->drop.drop_factor[3] = drop_factor[GetDsErmDmaLimitedThrdProfileMc(V, g_3_queueLimitedFactor_f, &ds)];
            }
        }
        else if (SYS_QUEUE_TYPE_EXCP_UC == p_queue_node->type)
        {
            if (is_dynamic == 0)
            {
                p_drop->drop.max_th[0] = GetDsErmDmaThrdProfileUc(V, g_0_queueLimitedThrd_f, &ds) * 8;
                p_drop->drop.max_th[1] = GetDsErmDmaThrdProfileUc(V, g_1_queueLimitedThrd_f, &ds) * 8;
                p_drop->drop.max_th[2] = GetDsErmDmaThrdProfileUc(V, g_2_queueLimitedThrd_f, &ds) * 8;
                p_drop->drop.max_th[3] = GetDsErmDmaThrdProfileUc(V, g_3_queueLimitedThrd_f, &ds) * 8;
            }
            else if (is_dynamic == 1)
            {
                p_drop->drop.drop_factor[0] = drop_factor[GetDsErmDmaThrdProfileUc(V, g_0_queueLimitedFactor_f, &ds)];
                p_drop->drop.drop_factor[1] = drop_factor[GetDsErmDmaThrdProfileUc(V, g_1_queueLimitedFactor_f, &ds)];
                p_drop->drop.drop_factor[2] = drop_factor[GetDsErmDmaThrdProfileUc(V, g_2_queueLimitedFactor_f, &ds)];
                p_drop->drop.drop_factor[3] = drop_factor[GetDsErmDmaThrdProfileUc(V, g_3_queueLimitedFactor_f, &ds)];
            }
        }
        else if (SYS_QUE_OFST_UC == q_ofst_type)
        {
            if (is_dynamic == 0)
            {
                p_drop->drop.max_th[0] = GetDsErmQueueThrdProfileUc(V, g_0_queueLimitedThrd_f, &ds) * 8;
                p_drop->drop.max_th[1] = GetDsErmQueueThrdProfileUc(V, g_1_queueLimitedThrd_f, &ds) * 8;
                p_drop->drop.max_th[2] = GetDsErmQueueThrdProfileUc(V, g_2_queueLimitedThrd_f, &ds) * 8;
                p_drop->drop.max_th[3] = GetDsErmQueueThrdProfileUc(V, g_3_queueLimitedThrd_f, &ds) * 8;
            }
            else if (is_dynamic == 1)
            {
                p_drop->drop.drop_factor[0] = drop_factor[GetDsErmQueueThrdProfileUc(V, g_0_queueLimitedFactor_f, &ds)];
                p_drop->drop.drop_factor[1] = drop_factor[GetDsErmQueueThrdProfileUc(V, g_1_queueLimitedFactor_f, &ds)];
                p_drop->drop.drop_factor[2] = drop_factor[GetDsErmQueueThrdProfileUc(V, g_2_queueLimitedFactor_f, &ds)];
                p_drop->drop.drop_factor[3] = drop_factor[GetDsErmQueueThrdProfileUc(V, g_3_queueLimitedFactor_f, &ds)];
            }
        }
        else if (SYS_QUE_OFST_MC == q_ofst_type)
        {
            if (is_dynamic == 0)
            {
                p_drop->drop.max_th[0] = GetDsErmQueueLimitedThrdProfileMc(V, g_0_queueLimitedThrd_f, &ds) * 8;
                p_drop->drop.max_th[1] = GetDsErmQueueLimitedThrdProfileMc(V, g_1_queueLimitedThrd_f, &ds) * 8;
                p_drop->drop.max_th[2] = GetDsErmQueueLimitedThrdProfileMc(V, g_2_queueLimitedThrd_f, &ds) * 8;
                p_drop->drop.max_th[3] = GetDsErmQueueLimitedThrdProfileMc(V, g_3_queueLimitedThrd_f, &ds) * 8;
            }
            else if (is_dynamic == 1)
            {
                p_drop->drop.drop_factor[0] = drop_factor[GetDsErmQueueLimitedThrdProfileMc(V, g_0_queueLimitedFactor_f, &ds)];
                p_drop->drop.drop_factor[1] = drop_factor[GetDsErmQueueLimitedThrdProfileMc(V, g_1_queueLimitedFactor_f, &ds)];
                p_drop->drop.drop_factor[2] = drop_factor[GetDsErmQueueLimitedThrdProfileMc(V, g_2_queueLimitedFactor_f, &ds)];
                p_drop->drop.drop_factor[3] = drop_factor[GetDsErmQueueLimitedThrdProfileMc(V, g_3_queueLimitedFactor_f, &ds)];
            }
        }
        p_drop->drop.is_dynamic = is_dynamic;
    }

    return CTC_E_NONE;
}


int32
sys_at_resrc_set_que_drop(uint8 lchip, uint8 is_dynamic, uint8 enable, ctc_qos_drop_t* que_drop,
                                                void* p_queue)
{
    uint32 cmd = 0;
    uint32 index = 0;
    uint8 drop_factor[11] = {15,14,13,12,11,10,9,0,1,2,3};
    ds_t ds_que_thrd_profile;
    ds_t ds_que_thrd_profile_mc;
    sys_queue_node_t* p_queue_node = (sys_queue_node_t*)p_queue;
    sys_qos_buffer_info_t* p_buffer_info = NULL;
    uint16 chan_id = 0;
    uint8 q_ofst = 0;
    uint8 q_ofst_type = 0;

    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    CTC_PTR_VALID_CHECK(p_queue_node);

    sal_memset(&ds_que_thrd_profile, 0, sizeof(ds_que_thrd_profile));
    sal_memset(&ds_que_thrd_profile_mc, 0, sizeof(ds_que_thrd_profile_mc));
    SYS_QOS_LCHIP_CONVERT(lchip, p_queue_node->pp_id);

    if (SYS_QUEUE_TYPE_NORMAL == p_queue_node->type || SYS_QUEUE_TYPE_EUNIT == p_queue_node->type)
    {
        q_ofst_type = p_queue_node->node[SYS_AT_COS_SUB_NODE_OFST(p_queue_node, que_drop->queue.class_prio)].type;
        q_ofst = p_queue_node->node[SYS_AT_COS_SUB_NODE_OFST(p_queue_node, que_drop->queue.class_prio)].ofst;
        if (SYS_QUE_OFST_UC == q_ofst_type)
        {
            CTC_MAX_VALUE_CHECK(q_ofst, SYS_AT_UC_QUEUE_NUM - 1);
            index = SYS_AT_QOS_ENCOD_DP_QUE_UC(p_queue_node->sub_chan, q_ofst);
            cmd = DRV_IOR(DsErmQueueThrdProfileUc_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_DP_EN(cmd, p_queue_node->dp_id), &ds_que_thrd_profile));
        }
        else if (SYS_QUE_OFST_MC == q_ofst_type)
        {
            CTC_MAX_VALUE_CHECK(q_ofst, SYS_AT_MC_QUEUE_NUM - 1);
            index = SYS_AT_QOS_ENCOD_CORE_QUE_MC(p_queue_node->sub_chan, p_queue_node->pp_id, p_queue_node->dp_id, q_ofst);
            cmd = DRV_IOR(DsErmQueueLimitedThrdProfileMc_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_PP_EN(cmd), &ds_que_thrd_profile_mc));
        }
    }
    else if (SYS_QUEUE_TYPE_EXCP == p_queue_node->type)
    {
        q_ofst_type = SYS_QUE_OFST_MC;
        cmd = DRV_IOR(DsErmDmaLimitedThrdProfileMc_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_queue_node->offset, DRV_CMD_PP_EN(cmd), &ds_que_thrd_profile_mc));
    }
    else if (SYS_QUEUE_TYPE_EXCP_UC == p_queue_node->type) /*DMA queue*/
    {
        q_ofst_type = SYS_QUE_OFST_UC;
        cmd = DRV_IOR(DsErmDmaThrdProfileUc_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_queue_node->offset, DRV_CMD_PP_EN(cmd), &ds_que_thrd_profile));
    }

    if (SYS_QUE_OFST_UC == q_ofst_type)
    {
        /*AT: dynamic should set thrd to max*/
        SetDsErmQueueThrdProfileUc(V, g_0_queueLimitedThrd_f, &ds_que_thrd_profile, (enable && !is_dynamic) ? que_drop->drop.max_th[0] / 8 : SYS_AT_LIMIT_MAX_THRD_UC);
        SetDsErmQueueThrdProfileUc(V, g_1_queueLimitedThrd_f, &ds_que_thrd_profile, (enable && !is_dynamic) ? que_drop->drop.max_th[1] / 8 : SYS_AT_LIMIT_MAX_THRD_UC);
        SetDsErmQueueThrdProfileUc(V, g_2_queueLimitedThrd_f, &ds_que_thrd_profile, (enable && !is_dynamic) ? que_drop->drop.max_th[2] / 8 : SYS_AT_LIMIT_MAX_THRD_UC);
        SetDsErmQueueThrdProfileUc(V, g_3_queueLimitedThrd_f, &ds_que_thrd_profile, (enable && !is_dynamic) ? que_drop->drop.max_th[3] / 8 : SYS_AT_LIMIT_MAX_THRD_UC);
        SetDsErmQueueThrdProfileUc(V, g_0_queueLimitedFactor_f, &ds_que_thrd_profile, drop_factor[que_drop->drop.drop_factor[0]]);
        SetDsErmQueueThrdProfileUc(V, g_1_queueLimitedFactor_f, &ds_que_thrd_profile, drop_factor[que_drop->drop.drop_factor[1]]);
        SetDsErmQueueThrdProfileUc(V, g_2_queueLimitedFactor_f, &ds_que_thrd_profile, drop_factor[que_drop->drop.drop_factor[2]]);
        SetDsErmQueueThrdProfileUc(V, g_3_queueLimitedFactor_f, &ds_que_thrd_profile, drop_factor[que_drop->drop.drop_factor[3]]);
        SetDsErmQueueThrdProfileUc(V, g_0_queueLimitedAutoEn_f, &ds_que_thrd_profile, (enable && is_dynamic) ? 1 : 0);
        SetDsErmQueueThrdProfileUc(V, g_1_queueLimitedAutoEn_f, &ds_que_thrd_profile, (enable && is_dynamic) ? 1 : 0);
        SetDsErmQueueThrdProfileUc(V, g_2_queueLimitedAutoEn_f, &ds_que_thrd_profile, (enable && is_dynamic) ? 1 : 0);
        SetDsErmQueueThrdProfileUc(V, g_3_queueLimitedAutoEn_f, &ds_que_thrd_profile, (enable && is_dynamic) ? 1 : 0);
    }
    if (SYS_QUE_OFST_MC == q_ofst_type)
    {
        SetDsErmQueueLimitedThrdProfileMc(V, g_0_queueLimitedThrd_f, &ds_que_thrd_profile_mc, (enable && !is_dynamic) ? que_drop->drop.max_th[0] / 8 : SYS_AT_LIMIT_MAX_THRD_MC);
        SetDsErmQueueLimitedThrdProfileMc(V, g_1_queueLimitedThrd_f, &ds_que_thrd_profile_mc, (enable && !is_dynamic) ? que_drop->drop.max_th[1] / 8 : SYS_AT_LIMIT_MAX_THRD_MC);
        SetDsErmQueueLimitedThrdProfileMc(V, g_2_queueLimitedThrd_f, &ds_que_thrd_profile_mc, (enable && !is_dynamic) ? que_drop->drop.max_th[2] / 8 : SYS_AT_LIMIT_MAX_THRD_MC);
        SetDsErmQueueLimitedThrdProfileMc(V, g_3_queueLimitedThrd_f, &ds_que_thrd_profile_mc, (enable && !is_dynamic) ? que_drop->drop.max_th[3] / 8 : SYS_AT_LIMIT_MAX_THRD_MC);
        SetDsErmQueueLimitedThrdProfileMc(V, g_0_queueLimitedFactor_f, &ds_que_thrd_profile_mc, drop_factor[que_drop->drop.drop_factor[0]]);
        SetDsErmQueueLimitedThrdProfileMc(V, g_1_queueLimitedFactor_f, &ds_que_thrd_profile_mc, drop_factor[que_drop->drop.drop_factor[1]]);
        SetDsErmQueueLimitedThrdProfileMc(V, g_2_queueLimitedFactor_f, &ds_que_thrd_profile_mc, drop_factor[que_drop->drop.drop_factor[2]]);
        SetDsErmQueueLimitedThrdProfileMc(V, g_3_queueLimitedFactor_f, &ds_que_thrd_profile_mc, drop_factor[que_drop->drop.drop_factor[3]]);
        SetDsErmQueueLimitedThrdProfileMc(V, g_0_queueLimitedAutoEn_f, &ds_que_thrd_profile_mc, (enable && is_dynamic) ? 1 : 0);
        SetDsErmQueueLimitedThrdProfileMc(V, g_1_queueLimitedAutoEn_f, &ds_que_thrd_profile_mc, (enable && is_dynamic) ? 1 : 0);
        SetDsErmQueueLimitedThrdProfileMc(V, g_2_queueLimitedAutoEn_f, &ds_que_thrd_profile_mc, (enable && is_dynamic) ? 1 : 0);
        SetDsErmQueueLimitedThrdProfileMc(V, g_3_queueLimitedAutoEn_f, &ds_que_thrd_profile_mc, (enable && is_dynamic) ? 1 : 0);
    }

    if (SYS_QUEUE_TYPE_NORMAL == p_queue_node->type || SYS_QUEUE_TYPE_EUNIT == p_queue_node->type)
    {
        if (SYS_QUE_OFST_UC == q_ofst_type)
        {
            index = SYS_AT_QOS_ENCOD_DP_QUE_UC(p_queue_node->sub_chan, q_ofst);
            cmd = DRV_IOW(DsErmQueueThrdProfileUc_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_DP_EN(cmd, p_queue_node->dp_id), &ds_que_thrd_profile));

            CTC_ERROR_RETURN(sys_at_get_channel_by_sub_channel(SYS_PP_BASE(lchip)+p_queue_node->pp_id, p_queue_node->dp_id, p_queue_node->sub_chan, &chan_id));
            p_buffer_info = ctc_vector_get(p_usw_queue_master[lchip]->buffer_info_vec, chan_id);
            if (p_buffer_info)
            {
                SetDsErmQueueThrdProfileUc(V, queueGuaranteedThrd_f, &ds_que_thrd_profile, GetDsErmQueueThrdProfileUc(V, queueGuaranteedThrd_f, &p_buffer_info->q_thrd_uc[q_ofst]));
                sal_memcpy(&p_buffer_info->q_thrd_uc[q_ofst], &ds_que_thrd_profile, sizeof(DsErmQueueThrdProfileUc_m));
            }
        }
        else if (SYS_QUE_OFST_MC == q_ofst_type)
        {
            index = SYS_AT_QOS_ENCOD_CORE_QUE_MC(p_queue_node->sub_chan, p_queue_node->pp_id, p_queue_node->dp_id, q_ofst);
            cmd = DRV_IOW(DsErmQueueLimitedThrdProfileMc_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_PP_EN(cmd), &ds_que_thrd_profile_mc));
        }

    }
    else if (SYS_QUEUE_TYPE_EXCP == p_queue_node->type)
    {
        cmd = DRV_IOW(DsErmDmaLimitedThrdProfileMc_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_queue_node->offset, DRV_CMD_PP_EN(cmd), &ds_que_thrd_profile_mc));
    }
    else if (SYS_QUEUE_TYPE_EXCP_UC == p_queue_node->type)
    {
        cmd = DRV_IOW(DsErmDmaThrdProfileUc_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_queue_node->offset, DRV_CMD_PP_EN(cmd), &ds_que_thrd_profile));
    }
    return CTC_E_NONE;
}

int32
_sys_at_queue_set_queue_flush_en(uint8 lchip, uint16 sub_chan, sys_queue_node_t* p_queue_node, uint8 ofst, uint8 enable)
{
    QMgrRdChanDiscardCtl_m chan_discard_ctl;
    DsQMgrGrpConfigUc_m group_cfg_uc;
    DsQMgrGrpConfigMc_m group_cfg_mc;
    uint32 discard_field[2];
    uint32 cmd = 0;
    uint16 value = 0;
    uint16 dp_chan = 0;
    uint16 index = 0;
    uint8 group_id = 0;
    uint8 pp_id = 0;
    uint8  dp_id = 0;

    /* p_queue_node not NULL means queue flush, else port flush */
    if (p_queue_node)
    {
        pp_id = p_queue_node->pp_id;
        dp_id = p_queue_node->dp_id;
        dp_chan = p_queue_node->sub_chan;
        SYS_AT_GROUP_ID(group_id, p_queue_node);
    }
    else
    {
        pp_id = SYS_CHAN_TO_PP_ID(sub_chan);
        dp_id = SYS_CHAN_TO_DP_ID(sub_chan);
        dp_chan = sub_chan & SYS_SUB_CHAN_MASK;
    }
    SYS_QOS_LCHIP_CONVERT(lchip, pp_id);

    index = dp_chan + dp_id * MCHIP_CAP(SYS_CAP_PER_DP_CHANNEL_NUM);

    cmd = DRV_IOR(QMgrRdChanDiscardCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &chan_discard_ctl));
    GetQMgrRdChanDiscardCtl(A, discardPacket_f, &chan_discard_ctl, discard_field);
    enable ? CTC_BMP_SET(discard_field, index) : CTC_BMP_UNSET(discard_field, index);
    SetQMgrRdChanDiscardCtl(A, discardPacket_f, &chan_discard_ctl,discard_field);
    cmd = DRV_IOW(QMgrRdChanDiscardCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &chan_discard_ctl));

    if (dp_chan == SYS_DMA_SUB_CHAN && p_queue_node && (SYS_QUEUE_TYPE_EXCP == p_queue_node->type || SYS_QUEUE_TYPE_EXCP_UC == p_queue_node->type) )
    {
        index = 2 * MCHIP_CAP(SYS_CAP_PER_DP_CHANNEL_NUM) + group_id;
    }

    if (!p_queue_node)
    {
        cmd = DRV_IOR(DsQMgrGrpConfigUc_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_PP_EN(cmd), &group_cfg_uc));
        cmd = DRV_IOR(DsQMgrGrpConfigMc_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_PP_EN(cmd), &group_cfg_mc));

        value = enable ? 0xFFF : 0;
        SetDsQMgrGrpConfigUc(V, flushEn_f, &group_cfg_uc, value);
        SetDsQMgrGrpConfigMc(V, flushEn_f, &group_cfg_mc, value);

        cmd = DRV_IOW(DsQMgrGrpConfigUc_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_PP_EN(cmd), &group_cfg_uc));
        cmd = DRV_IOW(DsQMgrGrpConfigMc_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_PP_EN(cmd), &group_cfg_mc));
    }
    else
    {
        if (SYS_QUE_OFST_UC == p_queue_node->node[ofst].type)
        {
            cmd = DRV_IOR(DsQMgrGrpConfigUc_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_PP_EN(cmd), &group_cfg_uc));

            value = GetDsQMgrGrpConfigUc(V, flushEn_f, &group_cfg_uc);
            enable ? CTC_BIT_SET(value, p_queue_node->node[ofst].ofst) : CTC_BIT_UNSET(value, p_queue_node->node[ofst].ofst);
            SetDsQMgrGrpConfigUc(V, flushEn_f, &group_cfg_uc, value);

            cmd = DRV_IOW(DsQMgrGrpConfigUc_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_PP_EN(cmd), &group_cfg_uc));
        }
        else if (SYS_QUE_OFST_MC == p_queue_node->node[ofst].type)
        {
            cmd = DRV_IOR(DsQMgrGrpConfigMc_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_PP_EN(cmd), &group_cfg_mc));

            value = GetDsQMgrGrpConfigMc(V, flushEn_f, &group_cfg_mc);
            enable ? CTC_BIT_SET(value, p_queue_node->node[ofst].ofst) : CTC_BIT_UNSET(value, p_queue_node->node[ofst].ofst);
            SetDsQMgrGrpConfigMc(V, flushEn_f, &group_cfg_mc, value);

            cmd = DRV_IOW(DsQMgrGrpConfigMc_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_PP_EN(cmd), &group_cfg_mc));
        }
    }

    return CTC_E_NONE;
}

/*level0: port, level1: queue*/
STATIC int32
_sys_at_queue_store_buffer_thrd(uint8 lchip, uint16 que_id, uint32 chan_id, uint16 sub_chan, uint8 pfc_en)
{
    sys_qos_buffer_info_t* p_buffer_info = NULL;
    sys_qos_buffer_info_t buffer_info_tmp;
    int32  ret = CTC_E_NONE;
    uint32 cmd = 0;
    uint32 gport = 0;
    uint16 index = 0;
    uint16 lport = 0;
    uint8  gchip = 0;
    uint8  pp_id = 0;
    uint8  dp_id = 0;
    uint8  dp_chan = 0;
    uint8  core_chan = 0;
    uint8  i = 0;
    uint8  ofst = 0;
    uint8  first_store = 0;

    sal_memset(&buffer_info_tmp, 0, sizeof(sys_qos_buffer_info_t));

    CTC_ERROR_RETURN(sys_usw_get_gchip_id(lchip, &gchip));
    lport = SYS_GET_LPORT_ID_WITH_CHAN(lchip, 0, chan_id);
    gport = CTC_MAP_LPORT_TO_GPORT(gchip, lport);

    pp_id = SYS_CHAN_TO_PP_ID(sub_chan);
    dp_id = SYS_CHAN_TO_DP_ID(sub_chan);
    dp_chan = sub_chan & SYS_SUB_CHAN_MASK;
    core_chan = SYS_AT_QOS_ENCOD_CORE_CHAN(dp_chan, pp_id, dp_id);
    SYS_QOS_LCHIP_CONVERT(lchip, pp_id);

    p_buffer_info = ctc_vector_get(p_usw_queue_master[lchip]->buffer_info_vec, chan_id);
    if (p_buffer_info && !pfc_en)
    {
        return CTC_E_NONE;
    }
    else if (!p_buffer_info)
    {
        MALLOC_ZERO(MEM_QUEUE_MODULE, p_buffer_info, sizeof(sys_qos_buffer_info_t));
        if (!p_buffer_info)
        {
            return CTC_E_NO_MEMORY;
        }
        first_store = 1;
    }

    if (first_store)
    {
        /* uc port limited & port guaranteed */
        cmd = DRV_IOR(DsErmPortThrdProfileUc_t, DRV_ENTRY_FLAG);
        CTC_ERROR_GOTO(DRV_IOCTL(lchip, dp_chan, DRV_CMD_DP_EN(cmd, dp_id), &p_buffer_info->port_thrd_uc), ret, error0);
        if(pfc_en)
        {
            sal_memcpy(&buffer_info_tmp.port_thrd_uc, &p_buffer_info->port_thrd_uc, sizeof(DsErmPortThrdProfileUc_m));
            SetDsErmPortThrdProfileUc(V, portGuaranteedThrd_f, &buffer_info_tmp.port_thrd_uc, 0);
        }
        cmd = DRV_IOW(DsErmPortThrdProfileUc_t, DRV_ENTRY_FLAG);
        CTC_ERROR_GOTO(DRV_IOCTL(lchip, dp_chan, DRV_CMD_DP_EN(cmd, dp_id), &buffer_info_tmp.port_thrd_uc), ret, error0);

        if(!pfc_en)
        {
            /* mc port limited */
            cmd = DRV_IOR(DsErmPortLimitedThrdProfileMc_t, DRV_ENTRY_FLAG);
            CTC_ERROR_GOTO(DRV_IOCTL(lchip, core_chan, DRV_CMD_PP_EN(cmd), &p_buffer_info->port_limited_mc), ret, error0);
            cmd = DRV_IOW(DsErmPortLimitedThrdProfileMc_t, DRV_ENTRY_FLAG);
            CTC_ERROR_GOTO(DRV_IOCTL(lchip, core_chan, DRV_CMD_PP_EN(cmd), &buffer_info_tmp.port_limited_mc), ret, error0);
        }
        /* mc port guaranteed */
        cmd = DRV_IOR(DsErmPortGuaranteedThrdProfileMc_t, DRV_ENTRY_FLAG);
        CTC_ERROR_GOTO(DRV_IOCTL(lchip, core_chan, DRV_CMD_PP_EN(cmd), &p_buffer_info->port_guaranteed_mc), ret, error0);
        cmd = DRV_IOW(DsErmPortGuaranteedThrdProfileMc_t, DRV_ENTRY_FLAG);
        CTC_ERROR_GOTO(DRV_IOCTL(lchip, core_chan, DRV_CMD_PP_EN(cmd), &buffer_info_tmp.port_guaranteed_mc), ret, error0);

        for (i=0; i<SYS_QOS_EGRESS_SC_POOL_NUM; i++)
        {
            /* uc port sc guaranteed */
            index = dp_chan << 2 | i;
            cmd = DRV_IOR(DsErmPortScThrdProfileUc_t, DRV_ENTRY_FLAG);
            CTC_ERROR_GOTO(DRV_IOCTL(lchip, index, DRV_CMD_DP_EN(cmd, dp_id), &p_buffer_info->port_sc_thrd_uc[i]), ret, error0);
            sal_memcpy(&buffer_info_tmp.port_sc_thrd_uc[i], &p_buffer_info->port_sc_thrd_uc[i], sizeof(DsErmPortScThrdProfileUc_m));
            SetDsErmPortScThrdProfileUc(V, portScGuaranteedThrd_f, &buffer_info_tmp.port_sc_thrd_uc[i], 0);
            cmd = DRV_IOW(DsErmPortScThrdProfileUc_t, DRV_ENTRY_FLAG);
            CTC_ERROR_GOTO(DRV_IOCTL(lchip, index, DRV_CMD_DP_EN(cmd, dp_id), &buffer_info_tmp.port_sc_thrd_uc[i]), ret, error0);

            /* mc port sc guaranteed */
            index = core_chan << 2 | i;
            cmd = DRV_IOR(DsErmPortScGuaranteedThrdProfileMc_t, DRV_ENTRY_FLAG);
            CTC_ERROR_GOTO(DRV_IOCTL(lchip, index, DRV_CMD_PP_EN(cmd), &p_buffer_info->port_sc_guaranteed_mc[i]), ret, error0);
            cmd = DRV_IOW(DsErmPortScGuaranteedThrdProfileMc_t, DRV_ENTRY_FLAG);
            CTC_ERROR_GOTO(DRV_IOCTL(lchip, index, DRV_CMD_PP_EN(cmd), &buffer_info_tmp.port_sc_guaranteed_mc[i]), ret, error0);
        }
    }

    /* queue guaranteed */
    for (i=0; i<MCHIP_CAP(SYS_CAP_QOS_QUEUE_NUM_PER_CHAN); i++)
    {
        sys_queue_node_t* p_que_node = NULL;
        ctc_qos_queue_id_t ctc_queue_id;
        uint16 queue_id = 0;

        ctc_queue_id.queue_type = CTC_QUEUE_TYPE_NETWORK_EGRESS;
        ctc_queue_id.queue_id = i;
        ctc_queue_id.gport = gport;
        CTC_ERROR_GOTO(sys_at_queue_get_queue_id(lchip,  &ctc_queue_id, &queue_id), ret, error0);
        p_que_node = ctc_vector_get(p_usw_queue_master[lchip]->queue_vec, queue_id);
        if (NULL == p_que_node)
        {
            SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Entry not exist \n");
            return CTC_E_NOT_EXIST;
        }
        if(pfc_en && queue_id != que_id)
        {
            continue;
        }
        for (ofst = 0; ofst < SYS_QUEUE_SUB_NODE_NUM; ofst++)
        {
            if (SYS_QUE_OFST_UC == p_que_node->node[ofst].type)
            {
                /* uc queue guaranteed */
                index = SYS_AT_QOS_ENCOD_DP_QUE_UC(dp_chan, p_que_node->node[ofst].ofst);
                cmd = DRV_IOR(DsErmQueueThrdProfileUc_t, DRV_ENTRY_FLAG);
                CTC_ERROR_GOTO(DRV_IOCTL(lchip, index, DRV_CMD_DP_EN(cmd, dp_id), &p_buffer_info->q_thrd_uc[p_que_node->node[ofst].ofst]), ret, error0);
                if(!pfc_en)
                {
                    sal_memcpy(&buffer_info_tmp.q_thrd_uc[p_que_node->node[ofst].ofst], &p_buffer_info->q_thrd_uc[p_que_node->node[ofst].ofst], sizeof(DsErmQueueThrdProfileUc_m));
                    SetDsErmQueueThrdProfileUc(V, queueGuaranteedThrd_f, &buffer_info_tmp.q_thrd_uc[p_que_node->node[ofst].ofst], 0);
                }
                else
                {
                    uint8 sc = GetDsErmQueueThrdProfileUc(V, sc_f, &p_buffer_info->q_thrd_uc[p_que_node->node[ofst].ofst]);
                    SetDsErmQueueThrdProfileUc(V, sc_f, &buffer_info_tmp.q_thrd_uc[p_que_node->node[ofst].ofst], sc);
                }
                cmd = DRV_IOW(DsErmQueueThrdProfileUc_t, DRV_ENTRY_FLAG);
                CTC_ERROR_GOTO(DRV_IOCTL(lchip, index, DRV_CMD_DP_EN(cmd, dp_id), &buffer_info_tmp.q_thrd_uc[p_que_node->node[ofst].ofst]), ret, error0);
            }
            else if (SYS_QUE_OFST_MC == p_que_node->node[ofst].type)
            {
                /* mc queue guaranteed */
                index = SYS_AT_QOS_ENCOD_CORE_QUE_MC(dp_chan, pp_id, dp_id, p_que_node->node[ofst].ofst);
                cmd = DRV_IOR(DsErmQueueGuaranteedThrdProfileMc_t, DRV_ENTRY_FLAG);
                CTC_ERROR_GOTO(DRV_IOCTL(lchip, index, DRV_CMD_PP_EN(cmd), &p_buffer_info->q_guaranteed_mc[p_que_node->node[ofst].ofst]), ret, error0);
                cmd = DRV_IOW(DsErmQueueGuaranteedThrdProfileMc_t, DRV_ENTRY_FLAG);
                CTC_ERROR_GOTO(DRV_IOCTL(lchip, index, DRV_CMD_PP_EN(cmd), &buffer_info_tmp.q_guaranteed_mc[p_que_node->node[ofst].ofst]), ret, error0);
            }
        }
    }

    if (first_store)
    {
        ctc_vector_add(p_usw_queue_master[lchip]->buffer_info_vec, chan_id, p_buffer_info);
    }
    return CTC_E_NONE;

error0:
    mem_free(p_buffer_info);
    return ret;
}

STATIC int32
_sys_at_queue_restore_buffer_thrd(uint8 lchip, uint16 que_id, uint32 chan_id, uint16 sub_chan, uint8 pfc_en)
{
    sys_qos_buffer_info_t* p_buffer_info = NULL;
    sys_qos_buffer_info_t buffer_info_tmp;
    DsErmPortScThrdProfileUc_m port_sc_thrd_uc;
    uint32 guaranteed = 0;
    uint32 cmd = 0;
    uint32 gport = 0;
    uint16 index = 0;
    uint16 lport = 0;
    uint8  gchip = 0;
    uint8  pp_id = 0;
    uint8  dp_id = 0;
    uint8  dp_chan = 0;
    uint8  core_chan = 0;
    uint8  i = 0;

    sal_memset(&buffer_info_tmp, 0, sizeof(sys_qos_buffer_info_t));

    CTC_ERROR_RETURN(sys_usw_get_gchip_id(lchip, &gchip));
    lport = SYS_GET_LPORT_ID_WITH_CHAN(lchip, 0, chan_id);
    gport = CTC_MAP_LPORT_TO_GPORT(gchip, lport);

    pp_id = SYS_CHAN_TO_PP_ID(sub_chan);
    dp_id = SYS_CHAN_TO_DP_ID(sub_chan);
    dp_chan = sub_chan & SYS_SUB_CHAN_MASK;
    core_chan = SYS_AT_QOS_ENCOD_CORE_CHAN(dp_chan, pp_id, dp_id);
    SYS_QOS_LCHIP_CONVERT(lchip, pp_id);

    p_buffer_info = ctc_vector_get(p_usw_queue_master[lchip]->buffer_info_vec, chan_id);
    if (!p_buffer_info)
    {
        return CTC_E_NONE;
    }

    /* queue guaranteed */
    for (i=0; i<MCHIP_CAP(SYS_CAP_QOS_QUEUE_NUM_PER_CHAN); i++)
    {
        sys_queue_node_t* p_que_node = NULL;
        DsErmQueueThrdProfileUc_m q_thrd_uc;
        ctc_qos_queue_id_t ctc_queue_id;
        uint16 queue_id = 0;
        uint8 ofst = 0;
        uint8 sc = 0;

        ctc_queue_id.queue_type = CTC_QUEUE_TYPE_NETWORK_EGRESS;
        ctc_queue_id.queue_id = i;
        ctc_queue_id.gport = gport;
        CTC_ERROR_RETURN(sys_at_queue_get_queue_id(lchip,  &ctc_queue_id, &queue_id));
        if(pfc_en && queue_id != que_id)
        {
            continue;
        }
        p_que_node = ctc_vector_get(p_usw_queue_master[lchip]->queue_vec, queue_id);
        if (NULL == p_que_node)
        {
            SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Entry not exist \n");
            return CTC_E_NOT_EXIST;
        }
        for (ofst = 0; ofst < SYS_QUEUE_SUB_NODE_NUM; ofst++)
        {
            if (SYS_QUE_OFST_UC == p_que_node->node[ofst].type)
            {
                /* uc queue guaranteed */
                index = SYS_AT_QOS_ENCOD_DP_QUE_UC(dp_chan, p_que_node->node[ofst].ofst);
                cmd = DRV_IOR(DsErmQueueThrdProfileUc_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_DP_EN(cmd, dp_id), &q_thrd_uc));
                sc = GetDsErmQueueThrdProfileUc(V, sc_f, &q_thrd_uc);
                SetDsErmQueueThrdProfileUc(V, sc_f, &p_buffer_info->q_thrd_uc[p_que_node->node[ofst].ofst], sc);
                cmd = DRV_IOW(DsErmQueueThrdProfileUc_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_DP_EN(cmd, dp_id), &p_buffer_info->q_thrd_uc[p_que_node->node[ofst].ofst]));
                sal_memset(&p_buffer_info->q_thrd_uc[p_que_node->node[ofst].ofst], 0, sizeof(DsErmQueueThrdProfileUc_m));
            }
            else if (SYS_QUE_OFST_MC == p_que_node->node[ofst].type)
            {
                /* mc queue guaranteed */
                index = SYS_AT_QOS_ENCOD_CORE_QUE_MC(dp_chan, pp_id, dp_id, p_que_node->node[ofst].ofst);
                cmd = DRV_IOW(DsErmQueueGuaranteedThrdProfileMc_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_PP_EN(cmd), &p_buffer_info->q_guaranteed_mc[p_que_node->node[ofst].ofst]));
                sal_memset(&p_buffer_info->q_guaranteed_mc[p_que_node->node[ofst].ofst], 0, sizeof(DsErmQueueGuaranteedThrdProfileMc_m));
            }
        }
    }

    if(0 != sal_memcmp(p_buffer_info->q_thrd_uc, buffer_info_tmp.q_thrd_uc, SYS_AT_UC_QUEUE_NUM * sizeof(DsErmQueueThrdProfileUc_m))
       ||0 != sal_memcmp(p_buffer_info->q_guaranteed_mc, buffer_info_tmp.q_guaranteed_mc, SYS_AT_MC_QUEUE_NUM * sizeof(DsErmQueueGuaranteedThrdProfileMc_m)))
    {
        return CTC_E_NONE;
    }

    /* uc port limited & port guaranteed */
    cmd = DRV_IOW(DsErmPortThrdProfileUc_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, dp_chan, DRV_CMD_DP_EN(cmd, dp_id), &p_buffer_info->port_thrd_uc));

    /* mc port limited */
    cmd = DRV_IOW(DsErmPortLimitedThrdProfileMc_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, core_chan, DRV_CMD_PP_EN(cmd), &p_buffer_info->port_limited_mc));

    /* mc port guaranteed */
    cmd = DRV_IOW(DsErmPortGuaranteedThrdProfileMc_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, core_chan, DRV_CMD_PP_EN(cmd), &p_buffer_info->port_guaranteed_mc));

    for (i=0; i<SYS_QOS_EGRESS_SC_POOL_NUM; i++)
    {
        /* uc port sc guaranteed */
        index = dp_chan << 2 | i;
        guaranteed = GetDsErmPortScThrdProfileUc(V, portScGuaranteedThrd_f, &p_buffer_info->port_sc_thrd_uc[i]);
        cmd = DRV_IOR(DsErmPortScThrdProfileUc_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_DP_EN(cmd, dp_id), &port_sc_thrd_uc));
        SetDsErmPortScThrdProfileUc(V, portScGuaranteedThrd_f, &port_sc_thrd_uc, guaranteed);
        cmd = DRV_IOW(DsErmPortScThrdProfileUc_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_DP_EN(cmd, dp_id), &port_sc_thrd_uc));

        /* mc port sc guaranteed */
        index = core_chan << 2 | i;
        cmd = DRV_IOW(DsErmPortScGuaranteedThrdProfileMc_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_PP_EN(cmd), &p_buffer_info->port_sc_guaranteed_mc[i]));
    }

    ctc_vector_del(p_usw_queue_master[lchip]->buffer_info_vec, chan_id);
    mem_free(p_buffer_info);

    return CTC_E_NONE;
}

STATIC int32
_sys_at_egs_mc_resrc_mgr_init(uint8 lchip, ctc_qos_global_cfg_t* p_cfg, uint32 min_pool_size)
{
    uint8 priority                 = 0;
    uint8 color                    = 0;
    uint8 step                     = 0;
    uint16 index                   = 0;
    uint32 field_val               = 0;
    uint32 cmd                     = 0;
    uint32 entry_num               = 0;
    uint32 pool_size[CTC_QOS_EGS_RESRC_POOL_MAX] = {0};
    uint32 total_pool_size         = 0;
    uint16 lport = 0;
    uint32 channel                = 0;
    uint8 mapped_sc = 0;
    uint8 gchip = 0;
    uint8* prio = NULL;
    sys_usw_dmps_port_info_t dmps_port_info = {0};
    ds_t ds;

    CTC_ERROR_RETURN(drv_get_gchip_id(lchip, &gchip));
    /*NON-UC*/
    /* 1. Buffer assign, total buffer cell is alloced by user */
    if (p_cfg->resrc_pool2.egs_pool_mode == CTC_QOS_RESRC_POOL_DISABLE)
    {
        pool_size[CTC_QOS_EGS_RESRC_SC0_POOL]       = MCHIP_CAP(SYS_CAP_QOS_DROP_TOTAL_NON_UC_POOL_SIZE) - 1536 - 4000;
        pool_size[CTC_QOS_EGS_RESRC_MIN_POOL]       = pool_size[CTC_QOS_EGS_RESRC_SC0_POOL] < min_pool_size ? 0 : min_pool_size;
        pool_size[CTC_QOS_EGS_RESRC_SC0_POOL]      -= pool_size[CTC_QOS_EGS_RESRC_MIN_POOL];
        pool_size[CTC_QOS_EGS_RESRC_SC3_POOL]       = 1536;     /* 1.5K */
        pool_size[CTC_QOS_EGS_RESRC_C2C_POOL]       = 0;
    }
    else if (p_cfg->resrc_pool2.egs_pool_mode == CTC_QOS_RESRC_POOL_USER_DEFINE)
    {
        sal_memcpy(pool_size, p_cfg->resrc_pool2.egs_pool_size, sizeof(pool_size));
    }
    else
    {
        return CTC_E_INVALID_PARAM;
    }

    total_pool_size = pool_size[CTC_QOS_EGS_RESRC_SC0_POOL] + pool_size[CTC_QOS_EGS_RESRC_SC1_POOL] + pool_size[CTC_QOS_EGS_RESRC_SC2_POOL] + pool_size[CTC_QOS_EGS_RESRC_SC3_POOL] +
                      pool_size[CTC_QOS_EGS_RESRC_MIN_POOL] + pool_size[CTC_QOS_EGS_RESRC_C2C_POOL];
    if (pool_size[CTC_QOS_EGS_RESRC_SC0_POOL] == 0 || total_pool_size > (MCHIP_CAP(SYS_CAP_QOS_DROP_TOTAL_NON_UC_POOL_SIZE) - 4000)) /* must have default pool */
    {
        return CTC_E_INVALID_PARAM;
    }
    total_pool_size = MCHIP_CAP(SYS_CAP_QOS_DROP_TOTAL_NON_UC_POOL_SIZE) - 4000;
    cmd = DRV_IOR(McResrcMgmtCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
    SetMcResrcMgmtCtl(V, g_noCareC2cPacket_f, &ds, 1);
    SetMcResrcMgmtCtl(V, g_noCareCriticalPacket_f, &ds, 1);
    SetMcResrcMgmtCtl(V, g_c2cPacketScEn_f, &ds, 1);
    SetMcResrcMgmtCtl(V, g_criticalPacketScEn_f, &ds, 1);
    SetMcResrcMgmtCtl(V, g_c2cPacketSc_f, &ds, CTC_QOS_EGS_RESRC_SC3_POOL);
    SetMcResrcMgmtCtl(V, g_criticalPacketSc_f, &ds, CTC_QOS_EGS_RESRC_SC3_POOL);
    cmd = DRV_IOW(McResrcMgmtCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));

    /* 2. configure register fields for egress resource management*/
    cmd = DRV_IOR(ErmMiscCtlMc_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
    SetErmMiscCtlMc(V, resourceCheckEn_f, &ds, 1);
    SetErmMiscCtlMc(V, guaranteedMode_f, &ds, 7);
    SetErmMiscCtlMc(V, thrdPassMode_f, &ds, 7);
    //SetErmMiscCtlMc(V, aqmSeedUpdateEn_f , &ds, 0xF0);
    SetErmMiscCtlMc(V, scRescMode_f , &ds, 0);
    SetErmMiscCtlMc(V, totalExcludeGuarantee_f, &ds, 1);
    SetErmMiscCtlMc(V, scExcludeGuarantee_f, &ds, 1);
    SetErmMiscCtlMc(V, aqmExcludeGuarantee_f, &ds, 1);
    //SetErmMiscCtlMc(V, glbAqmQueueDis_f, &ds, 0);
    //SetErmMiscCtlMc(V, glbAqmPortDis_f, &ds, 0);
    SetErmMiscCtlMc(V, glbQueueGuaranteedDis_f, &ds, 0); /*default use port min, not use queue min*/
    SetErmMiscCtlMc(V, glbQueueLimitedDis_f, &ds, 0);
    SetErmMiscCtlMc(V, glbPortScGuaranteedDis_f, &ds, 0);
    SetErmMiscCtlMc(V, glbPortScLimitedDis_f, &ds, 0);
    SetErmMiscCtlMc(V, glbPortGuaranteedDis_f, &ds, 0);
    SetErmMiscCtlMc(V, glbPortLimitedDis_f, &ds, 0);
    SetErmMiscCtlMc(V, continuousPortUseScRemain_f, &ds, 1);
    SetErmMiscCtlMc(V, continuousQueueUseScRemain_f, &ds, 1);
    cmd = DRV_IOW(ErmMiscCtlMc_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));

    /* 3. threshold config*/
    cmd = DRV_IOR(DsErmMiscThrdMc_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
    SetDsErmMiscThrdMc(V, g_0_c2cThrd_f, &ds, 0);
    SetDsErmMiscThrdMc(V, g_0_criticalThrd_f, &ds, 0);
    SetDsErmMiscThrdMc(V, g_0_totalThrd_f, &ds, total_pool_size);
    SetDsErmMiscThrdMc(V, g_0_spanThrd_f, &ds, 1024);
    SetDsErmMiscThrdMc(V, g_1_spanThrd_f, &ds, 1024);
    SetDsErmMiscThrdMc(V, g_1_c2cThrd_f, &ds, 0);
    SetDsErmMiscThrdMc(V, g_1_criticalThrd_f, &ds, 0);
    SetDsErmMiscThrdMc(V, g_1_totalThrd_f, &ds, 49152);
    cmd = DRV_IOW(DsErmMiscThrdMc_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));

    /* 4. sc threshold config, use 2 sc, sc0 : default pool; sc1: span pool, disable queue entry check*/
    cmd = DRV_IOR(DsErmScThrdMc_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
    SetDsErmScThrdMc(V, g_0_scEn_f, &ds, 1);
    SetDsErmScThrdMc(V, g_0_scThrd_f, &ds, pool_size[CTC_QOS_EGS_RESRC_SC0_POOL]);
    SetDsErmScThrdMc(V, g_1_scEn_f, &ds, pool_size[CTC_QOS_EGS_RESRC_SC1_POOL] ? 1 : 0);
    SetDsErmScThrdMc(V, g_1_scThrd_f, &ds, pool_size[CTC_QOS_EGS_RESRC_SC1_POOL]);
    SetDsErmScThrdMc(V, g_2_scEn_f, &ds, pool_size[CTC_QOS_EGS_RESRC_SC2_POOL] ? 1 : 0);
    SetDsErmScThrdMc(V, g_2_scThrd_f, &ds, pool_size[CTC_QOS_EGS_RESRC_SC2_POOL]);
    SetDsErmScThrdMc(V, g_3_scEn_f, &ds, (pool_size[CTC_QOS_EGS_RESRC_SC3_POOL]+pool_size[CTC_QOS_EGS_RESRC_C2C_POOL]) ? 1 : 0);
    SetDsErmScThrdMc(V, g_3_scThrd_f, &ds, (pool_size[CTC_QOS_EGS_RESRC_SC3_POOL]+pool_size[CTC_QOS_EGS_RESRC_C2C_POOL]));
    cmd = DRV_IOW(DsErmScThrdMc_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));

    /* 5. mapping profiles, use profile 0/1: all priority mapped to tc priority/2, default use sc 0*/
    for (lport = 0; lport < MCHIP_CAP(SYS_CAP_PORT_NUM_PER_CHIP); lport++)
    {
        dmps_port_info.gport = CTC_MAP_LPORT_TO_GPORT(gchip, lport);
        CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_CHAN_ID, &channel));
        if (SYS_DMPS_INVALID_CHAN_ID <= channel)
        {
            continue;
        }
        /* ppport to channel, cirtical packet use sc2*/
        if (SYS_IS_DMA_CHANNEL(channel))
        {
            mapped_sc = CTC_QOS_EGS_RESRC_SC3_POOL;
            prio = &priority;
        }
        else
        {
            color = 0;
            mapped_sc = 0;
            prio = &color;
        }
        cmd = DRV_IOR(DsResrcMgmtTxPrioMapMc_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, channel, cmd, &ds));
        step = DsResrcMgmtTxPrioMapMc_g0_1_mappedSc_f - DsResrcMgmtTxPrioMapMc_g0_0_mappedSc_f;
        for (priority = 0; priority < 16; priority++)
        {
            SetDsResrcMgmtTxPrioMapMc(V, g0_0_mappedTc_f + priority * step, &ds, *prio/2);
            SetDsResrcMgmtTxPrioMapMc(V, g0_0_mappedSc_f + priority * step, &ds, mapped_sc);
        }
        step = DsResrcMgmtTxPrioMapMc_g1_1_dropPrecedence_f - DsResrcMgmtTxPrioMapMc_g1_0_dropPrecedence_f;
        for (color = 0; color < 4; color++)
        {
            field_val = (color + 3) % 4;
            SetDsResrcMgmtTxPrioMapMc(V, g1_0_dropPrecedence_f + color * step, &ds, field_val);
        }
        cmd = DRV_IOW(DsResrcMgmtTxPrioMapMc_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, channel, cmd, &ds));
    }

    /* 8. configure port minimum guarantee profile, default port Min = 80*/
    sys_usw_ftm_query_table_entry_num(lchip, DsErmPortGuaranteedThrdProfileMc_t, &entry_num);
    entry_num = MCHIP_CAP(SYS_CAP_QOS_DROP_TOTAL_NON_UC_POOL_SIZE) < SYS_AT_NON_UC_BUFFER_SIZE_DEFAULT ? 0 : entry_num;
    for (index = 0; index < entry_num; index++)
    {
        cmd = DRV_IOR(DsErmPortGuaranteedThrdProfileMc_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &ds));
        SetDsErmPortGuaranteedThrdProfileMc(V, g_0_portGuaranteedThrd_f, &ds, SYS_AT_PORT_MIN_GUARANTEE);
        /*SetDsErmPortGuaranteedThrdProfileMc(V, g_1_portGuaranteedThrd_f, &ds, 20);*/
        cmd = DRV_IOW(DsErmPortGuaranteedThrdProfileMc_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &ds));
    }

    /* 9, default disable queue entry limited*/
    sal_memset(&ds, 0, sizeof(ds));
    SetDsErmQueueLimitedThrdProfileMc(V, g_0_queueLimitedAutoEn_f , &ds, 1);
    SetDsErmQueueLimitedThrdProfileMc(V, g_1_queueLimitedAutoEn_f , &ds, 1);
    SetDsErmQueueLimitedThrdProfileMc(V, g_2_queueLimitedAutoEn_f , &ds, 1);
    SetDsErmQueueLimitedThrdProfileMc(V, g_3_queueLimitedAutoEn_f , &ds, 1);
    SetDsErmQueueLimitedThrdProfileMc(V, g_4_queueLimitedThrd_f , &ds, SYS_AT_LIMIT_MAX_THRD_MC);
    SetDsErmQueueLimitedThrdProfileMc(V, g_5_queueLimitedThrd_f , &ds, SYS_AT_LIMIT_MAX_THRD_MC);
    SetDsErmQueueLimitedThrdProfileMc(V, g_6_queueLimitedThrd_f , &ds, SYS_AT_LIMIT_MAX_THRD_MC);
    SetDsErmQueueLimitedThrdProfileMc(V, g_7_queueLimitedThrd_f , &ds, SYS_AT_LIMIT_MAX_THRD_MC);
    cmd = DRV_IOW(DsErmQueueLimitedThrdProfileMc_t, DRV_ENTRY_FLAG);
    sys_usw_ftm_query_table_entry_num(lchip, DsErmQueueLimitedThrdProfileMc_t, &entry_num);
    for (index = 0; index < entry_num; index++)
    {
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &ds));
    }

    /* 10. disable port limited thrd check, port threshold profile alawy be 0*/
    sal_memset(&ds, 0, sizeof(ds));
    SetDsErmPortLimitedThrdProfileMc(V, g_0_portLimitedThrd_f, &ds, SYS_AT_LIMIT_MAX_THRD_MC);
    SetDsErmPortLimitedThrdProfileMc(V, g_1_portLimitedThrd_f, &ds, SYS_AT_LIMIT_MAX_THRD_MC);
    SetDsErmPortLimitedThrdProfileMc(V, g_2_portLimitedThrd_f, &ds, SYS_AT_LIMIT_MAX_THRD_MC);
    SetDsErmPortLimitedThrdProfileMc(V, g_3_portLimitedThrd_f, &ds, SYS_AT_LIMIT_MAX_THRD_MC);
    SetDsErmPortLimitedThrdProfileMc(V, g_4_portLimitedThrd_f, &ds, SYS_AT_LIMIT_MAX_THRD_MC);
    SetDsErmPortLimitedThrdProfileMc(V, g_5_portLimitedThrd_f, &ds, SYS_AT_LIMIT_MAX_THRD_MC);
    SetDsErmPortLimitedThrdProfileMc(V, g_6_portLimitedThrd_f, &ds, SYS_AT_LIMIT_MAX_THRD_MC);
    SetDsErmPortLimitedThrdProfileMc(V, g_7_portLimitedThrd_f, &ds, SYS_AT_LIMIT_MAX_THRD_MC);
    cmd = DRV_IOW(DsErmPortLimitedThrdProfileMc_t, DRV_ENTRY_FLAG);
    sys_usw_ftm_query_table_entry_num(lchip, DsErmPortLimitedThrdProfileMc_t, &entry_num);
    for (index = 0; index < entry_num; index++)
    {
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &ds));
    }

    /* 11. disable port sc limited thrd check, port threshold profile alawy be 0*/
    sal_memset(&ds, 0, sizeof(ds));
    SetDsErmPortScLimitedThrdProfileMc(V, g_0_portScLimitedThrd_f, &ds, SYS_AT_LIMIT_MAX_THRD_MC);
    SetDsErmPortScLimitedThrdProfileMc(V, g_1_portScLimitedThrd_f, &ds, SYS_AT_LIMIT_MAX_THRD_MC);
    SetDsErmPortScLimitedThrdProfileMc(V, g_2_portScLimitedThrd_f, &ds, SYS_AT_LIMIT_MAX_THRD_MC);
    SetDsErmPortScLimitedThrdProfileMc(V, g_3_portScLimitedThrd_f, &ds, SYS_AT_LIMIT_MAX_THRD_MC);
    SetDsErmPortScLimitedThrdProfileMc(V, g_4_portScLimitedThrd_f, &ds, SYS_AT_LIMIT_MAX_THRD_MC);
    SetDsErmPortScLimitedThrdProfileMc(V, g_5_portScLimitedThrd_f, &ds, SYS_AT_LIMIT_MAX_THRD_MC);
    SetDsErmPortScLimitedThrdProfileMc(V, g_6_portScLimitedThrd_f, &ds, SYS_AT_LIMIT_MAX_THRD_MC);
    SetDsErmPortScLimitedThrdProfileMc(V, g_7_portScLimitedThrd_f, &ds, SYS_AT_LIMIT_MAX_THRD_MC);
    cmd = DRV_IOW(DsErmPortScLimitedThrdProfileMc_t, DRV_ENTRY_FLAG);
    sys_usw_ftm_query_table_entry_num(lchip, DsErmPortScLimitedThrdProfileMc_t, &entry_num);
    for (index = 0; index < entry_num; index++)
    {
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &ds));
    }

    /* 12. configure Dma minimum guarantee profile, default port Min = 200*/
    sys_usw_ftm_query_table_entry_num(lchip, DsErmDmaGuaranteedThrdProfileMc_t, &entry_num);
    for (index = 0; index < entry_num; index++)
    {
        cmd = DRV_IOR(DsErmDmaGuaranteedThrdProfileMc_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &ds));
        SetDsErmDmaGuaranteedThrdProfileMc(V, g_0_queueGuaranteedThrd_f, &ds, 200);
        cmd = DRV_IOW(DsErmDmaGuaranteedThrdProfileMc_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &ds));
    }

    /* 12. default disable DMA queue entry limited*/
    sal_memset(&ds, 0, sizeof(ds));
    SetDsErmDmaLimitedThrdProfileMc(V, g_0_queueLimitedAutoEn_f , &ds, 1);
    SetDsErmDmaLimitedThrdProfileMc(V, g_1_queueLimitedAutoEn_f , &ds, 1);
    SetDsErmDmaLimitedThrdProfileMc(V, g_2_queueLimitedAutoEn_f , &ds, 1);
    SetDsErmDmaLimitedThrdProfileMc(V, g_3_queueLimitedAutoEn_f , &ds, 1);
    SetDsErmDmaLimitedThrdProfileMc(V, g_4_queueLimitedThrd_f , &ds, SYS_AT_LIMIT_MAX_THRD_MC);
    SetDsErmDmaLimitedThrdProfileMc(V, g_5_queueLimitedThrd_f , &ds, SYS_AT_LIMIT_MAX_THRD_MC);
    SetDsErmDmaLimitedThrdProfileMc(V, g_6_queueLimitedThrd_f , &ds, SYS_AT_LIMIT_MAX_THRD_MC);
    SetDsErmDmaLimitedThrdProfileMc(V, g_7_queueLimitedThrd_f , &ds, SYS_AT_LIMIT_MAX_THRD_MC);
    cmd = DRV_IOW(DsErmDmaLimitedThrdProfileMc_t, DRV_ENTRY_FLAG);
    sys_usw_ftm_query_table_entry_num(lchip, DsErmDmaLimitedThrdProfileMc_t, &entry_num);
    for (index = 0; index < entry_num; index++)
    {
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &ds));
    }
    return CTC_E_NONE;
}


STATIC int32
_sys_at_egs_uc_resrc_mgr_init(uint8 lchip, ctc_qos_global_cfg_t* p_cfg, uint32 min_pool_size)
{
    uint8 priority                 = 0;
    uint8 color                    = 0;
    uint8 step                     = 0;
    uint16 index                   = 0;
    uint16 index1                  = 0;
    uint16 channel                 = 0;
    uint32 field_val               = 0;
    uint32 cmd                     = 0;
    uint32 entry_num               = 0;
    uint32 pool_size[CTC_QOS_EGS_RESRC_POOL_MAX] = {0};
    uint32 total_pool_size = 0;
    uint8 mapped_sc = 0;
    uint8 gchip = 0;
    ds_t ds;

    CTC_ERROR_RETURN(drv_get_gchip_id(lchip, &gchip));
    /*UC*/
    /* 1. Buffer assign, total buffer cell is alloced by user */
    if (p_cfg->resrc_pool.egs_pool_mode == CTC_QOS_RESRC_POOL_DISABLE)
    {
        pool_size[CTC_QOS_EGS_RESRC_SC0_POOL]       = MCHIP_CAP(SYS_CAP_QOS_DROP_TOTAL_UC_POOL_SIZE) - 1536 - min_pool_size;
        pool_size[CTC_QOS_EGS_RESRC_SC3_POOL]       = 1536;     /* 1.5K */
        pool_size[CTC_QOS_EGS_RESRC_MIN_POOL]       = min_pool_size;
        pool_size[CTC_QOS_EGS_RESRC_C2C_POOL]       = 0;
    }
    else if (p_cfg->resrc_pool.egs_pool_mode == CTC_QOS_RESRC_POOL_USER_DEFINE)
    {
        sal_memcpy(pool_size, p_cfg->resrc_pool.egs_pool_size, sizeof(pool_size));
    }
    else
    {
        return CTC_E_INVALID_PARAM;
    }

    total_pool_size =  pool_size[CTC_QOS_EGS_RESRC_SC0_POOL] + pool_size[CTC_QOS_EGS_RESRC_SC1_POOL] + pool_size[CTC_QOS_EGS_RESRC_SC2_POOL]+ pool_size[CTC_QOS_EGS_RESRC_SC3_POOL] +
                       pool_size[CTC_QOS_EGS_RESRC_MIN_POOL] + pool_size[CTC_QOS_EGS_RESRC_C2C_POOL];
    if (pool_size[CTC_QOS_EGS_RESRC_SC0_POOL] == 0 || total_pool_size > MCHIP_CAP(SYS_CAP_QOS_DROP_TOTAL_UC_POOL_SIZE)) /* must have default pool */
    {
        return CTC_E_INVALID_PARAM;
    }
    total_pool_size =  MCHIP_CAP(SYS_CAP_QOS_DROP_TOTAL_UC_POOL_SIZE);
    cmd = DRV_IOR(ResrcMgmtCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
    SetResrcMgmtCtl(V, g_2_noCareC2cPacket_f, &ds, 1);
    SetResrcMgmtCtl(V, g_2_noCareCriticalPacket_f, &ds, 1);
    SetResrcMgmtCtl(V, g_2_c2cPacketScEn_f, &ds, 1);
    SetResrcMgmtCtl(V, g_2_criticalPacketScEn_f, &ds, 1);
    SetResrcMgmtCtl(V, g_2_c2cPacketSc_f, &ds, CTC_QOS_EGS_RESRC_SC3_POOL);
    SetResrcMgmtCtl(V, g_2_criticalPacketSc_f, &ds, CTC_QOS_EGS_RESRC_SC3_POOL);
    cmd = DRV_IOW(ResrcMgmtCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));

    /* 2. configure register fields for egress resource management*/
    cmd = DRV_IOR(ErmMiscCtlUc_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
    SetErmMiscCtlUc(V, resourceCheckEn_f, &ds, 1);
    SetErmMiscCtlUc(V, guaranteedMode_f, &ds, 7);
    SetErmMiscCtlUc(V, thrdPassMode_f, &ds, 7);
    SetErmMiscCtlUc(V, scRescMode_f , &ds, 0);
    SetErmMiscCtlUc(V, totalExcludeGuarantee_f, &ds, 1);
    SetErmMiscCtlUc(V, scExcludeGuarantee_f, &ds, 1);
    SetErmMiscCtlUc(V, aqmExcludeGuarantee_f, &ds, 1);
    SetErmMiscCtlUc(V, flowControlScEn_f, &ds, 7);
    SetErmMiscCtlUc(V, glbQueueGuaranteedDis_f, &ds, 0); /*default use port min, not use queue min*/
    SetErmMiscCtlUc(V, glbQueueLimitedDis_f, &ds, 0);
    SetErmMiscCtlUc(V, glbPortScGuaranteedDis_f, &ds, 0);
    SetErmMiscCtlUc(V, glbPortScLimitedDis_f, &ds, 0);
    SetErmMiscCtlUc(V, glbPortGuaranteedDis_f, &ds, 0);
    SetErmMiscCtlUc(V, glbPortLimitedDis_f, &ds, 0);
    SetErmMiscCtlUc(V, aqmQueGlbDis_f, &ds, 0);
    SetErmMiscCtlUc(V, portTcMicroBurstDis_f, &ds, 0);
    SetErmMiscCtlUc(V, portMicroBurstDis_f, &ds, 0);
    SetErmMiscCtlUc(V, aqmPortGlbDis_f, &ds, 0);
    SetErmMiscCtlUc(V, microBurstInformEn_f, &ds, 1);
    SetErmMiscCtlUc(V, portTcMicroBurstInformEn_f, &ds, 1);
    SetErmMiscCtlUc(V, headroomEligibleMode_f, &ds, 0x7);
    cmd = DRV_IOW(ErmMiscCtlUc_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));

    /* 3. threshold config*/
    cmd = DRV_IOR(DsErmMiscThrdUc_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
    SetDsErmMiscThrdUc(V, c2cThrd_f, &ds, 0);
    SetDsErmMiscThrdUc(V, criticalThrd_f, &ds, 0);
    SetDsErmMiscThrdUc(V, totalThrd_f, &ds, total_pool_size);
    cmd = DRV_IOW(DsErmMiscThrdUc_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));

    /* 4. sc threshold config, use 2 sc, sc0 : default pool; sc1: span pool*/
    cmd = DRV_IOR(DsErmScThrdUc_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
    SetDsErmScThrdUc(V, g_0_scEn_f, &ds, 1);
    SetDsErmScThrdUc(V, g_0_scThrd_f, &ds, pool_size[CTC_QOS_EGS_RESRC_SC0_POOL]);
    SetDsErmScThrdUc(V, g_1_scEn_f, &ds, pool_size[CTC_QOS_EGS_RESRC_SC1_POOL] ? 1 : 0);
    SetDsErmScThrdUc(V, g_1_scThrd_f, &ds, pool_size[CTC_QOS_EGS_RESRC_SC1_POOL]);
    SetDsErmScThrdUc(V, g_2_scEn_f, &ds, pool_size[CTC_QOS_EGS_RESRC_SC2_POOL] ? 1 : 0);
    SetDsErmScThrdUc(V, g_2_scThrd_f, &ds, pool_size[CTC_QOS_EGS_RESRC_SC2_POOL]);
    SetDsErmScThrdUc(V, g_3_scEn_f, &ds, (pool_size[CTC_QOS_EGS_RESRC_SC3_POOL] + pool_size[CTC_QOS_EGS_RESRC_C2C_POOL]) ? 1 : 0);
    SetDsErmScThrdUc(V, g_3_scThrd_f, &ds, (pool_size[CTC_QOS_EGS_RESRC_SC3_POOL] + pool_size[CTC_QOS_EGS_RESRC_C2C_POOL]));
    cmd = DRV_IOW(DsErmScThrdUc_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));

    /* 5. mapping profiles, use profile 0/1: all priority mapped to tc priority/2, default use sc 0*/
    for (channel = 0; channel < 512; channel++)
    {
        /*ppport to channel, cirtical packet use sc2*/
        mapped_sc = SYS_IS_DMA_CHANNEL(channel) ? CTC_QOS_EGS_RESRC_SC3_POOL : 0;
        cmd = DRV_IOR(DsResrcMgmtTxPrioMapUc_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, channel, cmd, &ds));
        step = DsResrcMgmtTxPrioMapUc_g0_1_mappedSc_f - DsResrcMgmtTxPrioMapUc_g0_0_mappedSc_f;
        for (priority = 0; priority < 16; priority++)
        {
            SetDsResrcMgmtTxPrioMapUc(V, g0_0_mappedTc_f + priority * step, &ds, priority / 2);
            SetDsResrcMgmtTxPrioMapUc(V, g0_0_mappedSc_f + priority * step, &ds, mapped_sc);
        }
        step = DsResrcMgmtTxPrioMapUc_g1_1_dropPrecedence_f - DsResrcMgmtTxPrioMapUc_g1_0_dropPrecedence_f;
        for (color = 0; color < 4; color++)
        {
            field_val = (color + 3) % 4;
            SetDsResrcMgmtTxPrioMapUc(V, g1_0_dropPrecedence_f + color * step, &ds, field_val);
        }
        cmd = DRV_IOW(DsResrcMgmtTxPrioMapUc_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, channel, cmd, &ds));
    }

    /*EMU_MODIFY*/
    /* default disable queue guarantee*/
    sal_memset(&ds, 0, sizeof(ds));
    SetDsErmQueueThrdProfileUc(V, g_0_queueLimitedAutoEn_f , &ds, 1);
    SetDsErmQueueThrdProfileUc(V, g_1_queueLimitedAutoEn_f , &ds, 1);
    SetDsErmQueueThrdProfileUc(V, g_2_queueLimitedAutoEn_f , &ds, 1);
    SetDsErmQueueThrdProfileUc(V, g_3_queueLimitedAutoEn_f , &ds, 1);
    SetDsErmQueueThrdProfileUc(V, g_0_queueLimitedThrd_f, &ds, SYS_AT_LIMIT_MAX_THRD_UC);
    SetDsErmQueueThrdProfileUc(V, g_1_queueLimitedThrd_f, &ds, SYS_AT_LIMIT_MAX_THRD_UC);
    SetDsErmQueueThrdProfileUc(V, g_2_queueLimitedThrd_f, &ds, SYS_AT_LIMIT_MAX_THRD_UC);
    SetDsErmQueueThrdProfileUc(V, g_3_queueLimitedThrd_f, &ds, SYS_AT_LIMIT_MAX_THRD_UC);
    SetDsErmQueueThrdProfileUc(V, queueGuaranteedThrd_f, &ds, 0x3FF);
    sys_usw_ftm_query_table_entry_num(lchip, DsErmQueueThrdProfileUc_t, &entry_num);
    cmd = DRV_IOW(DsErmQueueThrdProfileUc_t, DRV_ENTRY_FLAG);
    for (index = 0; index < entry_num; index++)
    {
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &ds));
    }

    /* 8. configure port minimum guarantee profile, default port Min = 80*/
    sal_memset(&ds, 0, sizeof(ds));
    SetDsErmPortThrdProfileUc(V, g_0_portLimitedThrd_f, &ds, SYS_AT_LIMIT_MAX_THRD_UC);
    SetDsErmPortThrdProfileUc(V, g_1_portLimitedThrd_f, &ds, SYS_AT_LIMIT_MAX_THRD_UC);
    SetDsErmPortThrdProfileUc(V, g_2_portLimitedThrd_f, &ds, SYS_AT_LIMIT_MAX_THRD_UC);
    SetDsErmPortThrdProfileUc(V, g_3_portLimitedThrd_f, &ds, SYS_AT_LIMIT_MAX_THRD_UC);
    SetDsErmPortThrdProfileUc(V, portGuaranteedThrd_f, &ds, SYS_AT_PORT_MIN_GUARANTEE);
    cmd = DRV_IOW(DsErmPortThrdProfileUc_t, DRV_ENTRY_FLAG);

    sys_usw_ftm_query_table_entry_num(lchip, DsErmPortThrdProfileUc_t, &entry_num);
    for (index = 0; index < entry_num; index++)
    {
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &ds));
    }

    /*EMU_MODIFY*/
    /*11. config ewma weight*/
    sys_usw_ftm_query_table_entry_num(lchip, DsAqmQueueCfg_t, &entry_num);
    step = DsAqmQueueCfg_g_1_avgQueueLenResetEn_f - DsAqmQueueCfg_g_0_avgQueueLenResetEn_f;
    for (index = 0; index < entry_num; index++)/*set all dp*/
    {
        cmd = DRV_IOR(DsAqmQueueCfg_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &ds));
        for(index1 = 0; index1 < 4; index1++)
        {
            SetDsAqmQueueCfg(V, g_0_avgQueueLenResetEn_f + step * index1, &ds, 1);
            SetDsAqmQueueCfg(V, g_0_ewmaWeightFactor_f + step * index1, &ds, 1);
        }
        cmd = DRV_IOW(DsAqmQueueCfg_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &ds));
    }

    sys_usw_ftm_query_table_entry_num(lchip, DsAqmPortCfg_t, &entry_num);
    for (index = 0; index < entry_num; index++)/*set all dp*/
    {
        cmd = DRV_IOR(DsAqmPortCfg_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &ds));
        SetDsAqmPortCfg(V, avgPortLenResetEn_f, &ds, 1);
        SetDsAqmPortCfg(V, ewmaWeightFactor_f, &ds, 1);
        cmd = DRV_IOW(DsAqmPortCfg_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &ds));
    }

    /* 13, enable aqm queue scan*/
    cmd = DRV_IOR(AqmQueueScanCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
    SetAqmQueueScanCtl(V, aqmQueueScanEn_f , &ds, 1);
    SetAqmQueueScanCtl(V, aqmQueueScanInterval_f, &ds, 10);
    cmd = DRV_IOW(AqmQueueScanCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));

    /* 13, disable aqm queue/port (queue/port wred)*/
    cmd = DRV_IOR(DsAqmQueueThrdProfile_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
    SetDsAqmQueueThrdProfile(V, g_0_wredAvgMinLen_f, &ds, SYS_AT_LIMIT_MAX_THRD_UC);
    SetDsAqmQueueThrdProfile(V, g_1_wredAvgMinLen_f, &ds, SYS_AT_LIMIT_MAX_THRD_UC);
    SetDsAqmQueueThrdProfile(V, g_2_wredAvgMinLen_f, &ds, SYS_AT_LIMIT_MAX_THRD_UC);
    SetDsAqmQueueThrdProfile(V, g_3_wredAvgMinLen_f, &ds, SYS_AT_LIMIT_MAX_THRD_UC);
    cmd = DRV_IOW(DsAqmQueueThrdProfile_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));

    /*default disable port wred*/
    sal_memset(&ds, 0, sizeof(ds));
    SetDsAqmPortThrdProfile(V, g_0_wredAvgMaxLen_f, &ds, SYS_AT_LIMIT_MAX_THRD_UC);
    SetDsAqmPortThrdProfile(V, g_1_wredAvgMaxLen_f, &ds, SYS_AT_LIMIT_MAX_THRD_UC);
    SetDsAqmPortThrdProfile(V, g_2_wredAvgMaxLen_f, &ds, SYS_AT_LIMIT_MAX_THRD_UC);
    SetDsAqmPortThrdProfile(V, g_3_wredAvgMaxLen_f, &ds, SYS_AT_LIMIT_MAX_THRD_UC);
    SetDsAqmPortThrdProfile(V, g_0_wredAvgMinLen_f, &ds, SYS_AT_LIMIT_MAX_THRD_UC);
    SetDsAqmPortThrdProfile(V, g_1_wredAvgMinLen_f, &ds, SYS_AT_LIMIT_MAX_THRD_UC);
    SetDsAqmPortThrdProfile(V, g_2_wredAvgMinLen_f, &ds, SYS_AT_LIMIT_MAX_THRD_UC);
    SetDsAqmPortThrdProfile(V, g_3_wredAvgMinLen_f, &ds, SYS_AT_LIMIT_MAX_THRD_UC);
    sys_usw_ftm_query_table_entry_num(lchip, DsAqmPortThrdProfile_t, &entry_num);
    cmd = DRV_IOW(DsAqmPortThrdProfile_t, DRV_ENTRY_FLAG);
    for (index = 0; index < entry_num; index++)
    {
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &ds));
    }

    /*default disable port sc limit check*/
    sal_memset(&ds, 0, sizeof(ds));
    SetDsErmPortScThrdProfileUc(V, g_0_portScLimitedThrd_f, &ds, SYS_AT_LIMIT_MAX_THRD_UC);
    SetDsErmPortScThrdProfileUc(V, g_1_portScLimitedThrd_f, &ds, SYS_AT_LIMIT_MAX_THRD_UC);
    SetDsErmPortScThrdProfileUc(V, g_2_portScLimitedThrd_f, &ds, SYS_AT_LIMIT_MAX_THRD_UC);
    SetDsErmPortScThrdProfileUc(V, g_3_portScLimitedThrd_f, &ds, SYS_AT_LIMIT_MAX_THRD_UC);
    sys_usw_ftm_query_table_entry_num(lchip, DsErmPortScThrdProfileUc_t, &entry_num);
    cmd = DRV_IOW(DsErmPortScThrdProfileUc_t, DRV_ENTRY_FLAG);
    for (index = 0; index < entry_num; index++)
    {
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &ds));
    }

    /* 14, default disable ecn mark, and set resrc check mode*/
    // sys_usw_ftm_query_table_entry_num(lchip, DsErmQueueThrdProfileUc_t, &entry_num);
    // for (index = 0; index < entry_num; index++)
    // {
    //     cmd = DRV_IOR(DsErmQueueThrdProfileUc_t, DRV_ENTRY_FLAG);
    //     CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &ds));
    //     SetDsErmQueueThrdProfileUc(V, g_0_queueLimitedAutoEn_f , &ds, 1);
    //     SetDsErmQueueThrdProfileUc(V, g_1_queueLimitedAutoEn_f , &ds, 1);
    //     SetDsErmQueueThrdProfileUc(V, g_2_queueLimitedAutoEn_f , &ds, 1);
    //     SetDsErmQueueThrdProfileUc(V, g_3_queueLimitedAutoEn_f , &ds, 1);
    //     SetDsErmQueueThrdProfileUc(V, g_0_queueLimitedThrd_f, &ds, SYS_AT_LIMIT_MAX_THRD_UC);
    //     SetDsErmQueueThrdProfileUc(V, g_1_queueLimitedThrd_f, &ds, SYS_AT_LIMIT_MAX_THRD_UC);
    //     SetDsErmQueueThrdProfileUc(V, g_2_queueLimitedThrd_f, &ds, SYS_AT_LIMIT_MAX_THRD_UC);
    //     SetDsErmQueueThrdProfileUc(V, g_3_queueLimitedThrd_f, &ds, SYS_AT_LIMIT_MAX_THRD_UC);
    //     cmd = DRV_IOW(DsErmQueueThrdProfileUc_t, DRV_ENTRY_FLAG);
    //     CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &ds));
    // }

    /* 15, configure Dma minimum guarantee profile, default port Min = 200*/
    sal_memset(&ds, 0, sizeof(ds));
    SetDsErmDmaThrdProfileUc(V, g_0_queueLimitedAutoEn_f , &ds, 1);
    SetDsErmDmaThrdProfileUc(V, g_1_queueLimitedAutoEn_f , &ds, 1);
    SetDsErmDmaThrdProfileUc(V, g_2_queueLimitedAutoEn_f , &ds, 1);
    SetDsErmDmaThrdProfileUc(V, g_3_queueLimitedAutoEn_f , &ds, 1);
    SetDsErmDmaThrdProfileUc(V, g_0_queueLimitedThrd_f , &ds, SYS_AT_LIMIT_MAX_THRD_UC);
    SetDsErmDmaThrdProfileUc(V, g_1_queueLimitedThrd_f , &ds, SYS_AT_LIMIT_MAX_THRD_UC);
    SetDsErmDmaThrdProfileUc(V, g_2_queueLimitedThrd_f , &ds, SYS_AT_LIMIT_MAX_THRD_UC);
    SetDsErmDmaThrdProfileUc(V, g_3_queueLimitedThrd_f , &ds, SYS_AT_LIMIT_MAX_THRD_UC);
    SetDsErmDmaThrdProfileUc(V, queueGuaranteedThrd_f, &ds, 200);
    sys_usw_ftm_query_table_entry_num(lchip, DsErmDmaThrdProfileUc_t, &entry_num);
    cmd = DRV_IOW(DsErmDmaThrdProfileUc_t, DRV_ENTRY_FLAG);
    for (index = 0; index < entry_num; index++)
    {
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &ds));
    }
    return CTC_E_NONE;
}

STATIC int32
_sys_at_igs_mc_resrc_mgr_init(uint8 lchip, ctc_qos_global_cfg_t* p_cfg, uint32 min_pool_size)
{

    uint8 priority                 = 0;
    uint8 color                    = 0;
    uint8 step                     = 0;
    uint16 index                   = 0;
    uint16 channel                 = 0;
    uint32 cmd                     = 0;
    uint32 field_val               = 0;
    uint32 entry_num               = 0;
    uint32 pool_size[CTC_QOS_IGS_RESRC_POOL_MAX] = {0};
    uint32 total_pool_size = 0;
    ds_t ds;

    /*NON-UC*/
    /* 1. Buffer assign, total buffer cell is alloced by user*/
    if (p_cfg->resrc_pool2.igs_pool_mode == CTC_QOS_RESRC_POOL_DISABLE)
    {
        pool_size[CTC_QOS_IGS_RESRC_MIN_POOL]       = MCHIP_CAP(SYS_CAP_QOS_DROP_TOTAL_NON_UC_POOL_SIZE) < min_pool_size ? 0 : min_pool_size;
        pool_size[CTC_QOS_IGS_RESRC_SC0_POOL]       = MCHIP_CAP(SYS_CAP_QOS_DROP_TOTAL_NON_UC_POOL_SIZE) - pool_size[CTC_QOS_IGS_RESRC_MIN_POOL];
        pool_size[CTC_QOS_IGS_RESRC_C2C_POOL]       = 0;
        pool_size[CTC_QOS_IGS_RESRC_CONTROL_POOL]   = 0;
    }
    else if (p_cfg->resrc_pool2.igs_pool_mode == CTC_QOS_RESRC_POOL_USER_DEFINE)
    {
        sal_memcpy(pool_size, p_cfg->resrc_pool2.igs_pool_size, sizeof(pool_size));
    }
    else
    {
        return CTC_E_INVALID_PARAM;
    }

    total_pool_size = pool_size[CTC_QOS_IGS_RESRC_SC0_POOL] + pool_size[CTC_QOS_IGS_RESRC_SC1_POOL] + pool_size[CTC_QOS_IGS_RESRC_SC2_POOL] + pool_size[CTC_QOS_IGS_RESRC_SC3_POOL] +
                      pool_size[CTC_QOS_IGS_RESRC_MIN_POOL] + pool_size[CTC_QOS_IGS_RESRC_C2C_POOL] + pool_size[CTC_QOS_IGS_RESRC_CONTROL_POOL];
    if (pool_size[CTC_QOS_IGS_RESRC_SC0_POOL] == 0 || total_pool_size > MCHIP_CAP(SYS_CAP_QOS_DROP_TOTAL_NON_UC_POOL_SIZE))
    {
        return CTC_E_INVALID_PARAM;
    }
    total_pool_size = MCHIP_CAP(SYS_CAP_QOS_DROP_TOTAL_NON_UC_POOL_SIZE);
    /* 2. enable ingress resource management*/
    cmd = DRV_IOR(IrmMiscCtlMc_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
    SetIrmMiscCtlMc(V, resourceCheckEn_f , &ds, 1);
    SetIrmMiscCtlMc(V, continuousPortUseScRemain_f , &ds, 1);
    SetIrmMiscCtlMc(V, continuousPortTcUseScRemain_f , &ds, 1);
    SetIrmMiscCtlMc(V, flowControlScEn_f , &ds, 0);
    SetIrmMiscCtlMc(V, flowControlUsePortCnt_f , &ds, 0);
    SetIrmMiscCtlMc(V, glbPortGuaranteedDis_f , &ds, 0);
    SetIrmMiscCtlMc(V, glbPortLimitedDis_f , &ds, 1);
    SetIrmMiscCtlMc(V, glbPortScGuaranteedDis_f , &ds, 0);
    SetIrmMiscCtlMc(V, glbPortScLimitedDis_f , &ds, 0);
    SetIrmMiscCtlMc(V, glbPortTcGuaranteedDis_f , &ds, 1);
    SetIrmMiscCtlMc(V, glbPortTcLimitedDis_f , &ds, 1);
    SetIrmMiscCtlMc(V, scExcludeGuarantee_f , &ds, 1);
    SetIrmMiscCtlMc(V, totalExcludeGuarantee_f , &ds, 1);
    SetIrmMiscCtlMc(V, guaranteedMode_f, &ds, 7);
    SetIrmMiscCtlMc(V, thrdPassMode_f, &ds, 7);
    SetIrmMiscCtlMc(V, headroomOpEn_f, &ds, 0);
    SetIrmMiscCtlMc(V, scRescMode_f , &ds, 0);
    cmd = DRV_IOW(IrmMiscCtlMc_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));

    cmd = DRV_IOR(ResrcMgmtCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
    if (0 == pool_size[CTC_QOS_IGS_RESRC_C2C_POOL])
    {
        SetResrcMgmtCtl(V, g_1_noCareC2cPacket_f, &ds, 1);
    }
    if (0 == pool_size[CTC_QOS_IGS_RESRC_CONTROL_POOL])
    {
        SetResrcMgmtCtl(V, g_1_noCareCriticalPacket_f, &ds, 1);
    }
    cmd = DRV_IOW(ResrcMgmtCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));

    /* 3. threshold config */
    cmd = DRV_IOR(DsIrmMiscThrdMc_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
    SetDsIrmMiscThrdMc(V, c2cThrd_f, &ds, pool_size[CTC_QOS_IGS_RESRC_C2C_POOL]);
    SetDsIrmMiscThrdMc(V, criticalThrd_f, &ds, pool_size[CTC_QOS_IGS_RESRC_CONTROL_POOL]);
    SetDsIrmMiscThrdMc(V, totalThrd_f, &ds, total_pool_size);
    cmd = DRV_IOW(DsIrmMiscThrdMc_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));

    /* 4. configure default pool threshold, only use one sc */
    cmd = DRV_IOR(DsIrmScThrdMc_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
    SetDsIrmScThrdMc(V, g_0_scEn_f, &ds, 1);
    SetDsIrmScThrdMc(V, g_0_scThrd_f, &ds, (pool_size[CTC_QOS_IGS_RESRC_SC0_POOL]+pool_size[CTC_QOS_IGS_RESRC_C2C_POOL]+pool_size[CTC_QOS_IGS_RESRC_CONTROL_POOL]));
    SetDsIrmScThrdMc(V, g_1_scEn_f, &ds, pool_size[CTC_QOS_IGS_RESRC_SC1_POOL] ? 1 : 0);
    SetDsIrmScThrdMc(V, g_1_scThrd_f, &ds, pool_size[CTC_QOS_IGS_RESRC_SC1_POOL]);
    SetDsIrmScThrdMc(V, g_2_scEn_f, &ds, pool_size[CTC_QOS_IGS_RESRC_SC2_POOL] ? 1 : 0);
    SetDsIrmScThrdMc(V, g_2_scThrd_f, &ds, pool_size[CTC_QOS_IGS_RESRC_SC2_POOL]);
    SetDsIrmScThrdMc(V, g_3_scEn_f, &ds, pool_size[CTC_QOS_IGS_RESRC_SC3_POOL] ? 1 : 0);
    SetDsIrmScThrdMc(V, g_3_scThrd_f, &ds, pool_size[CTC_QOS_IGS_RESRC_SC3_POOL]);
    cmd = DRV_IOW(DsIrmScThrdMc_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));

    if(pool_size[CTC_QOS_IGS_RESRC_SC1_POOL])
    {
        cmd = DRV_IOR(BufferStoreCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
        SetBufferStoreCtl(V, pureLogScEn_f, &ds, 1);
        SetBufferStoreCtl(V, pureLogSc_f, &ds, CTC_QOS_IGS_RESRC_SC1_POOL);
        cmd = DRV_IOW(BufferStoreCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
    }
    /* 5. all priority mapped to tc 0 and sc 0 */
    for (channel = 0; channel < 512; channel++)
    {
        cmd = DRV_IOR(DsResrcMgmtRxPrioMapMc_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, channel, cmd, &ds));
        step = DsResrcMgmtRxPrioMapMc_g0_1_mappedSc_f - DsResrcMgmtRxPrioMapMc_g0_0_mappedSc_f;
        for (priority = 0; priority < 16; priority++)
        {
            SetDsResrcMgmtRxPrioMapMc(V, g0_0_mappedTc_f + priority * step, &ds, 0);
            SetDsResrcMgmtRxPrioMapMc(V, g0_0_mappedSc_f + priority * step, &ds, 0);
        }
        step = DsResrcMgmtRxPrioMapMc_g1_1_dropPrecedence_f - DsResrcMgmtRxPrioMapMc_g1_0_dropPrecedence_f;
        for (color = 0; color < 4; color++)
        {
            field_val = (color + 3) % 4;
            SetDsResrcMgmtRxPrioMapMc(V, g1_0_dropPrecedence_f + color * step, &ds, field_val);
        }
        cmd = DRV_IOW(DsResrcMgmtRxPrioMapMc_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, channel, cmd, &ds));
    }

    /* 7. configure port minimum guarantee, default port Min = 80*/
    sys_usw_ftm_query_table_entry_num(lchip, DsIrmPortGuaranteedThrdProfileMc_t, &entry_num);
    entry_num = MCHIP_CAP(SYS_CAP_QOS_DROP_TOTAL_NON_UC_POOL_SIZE) < SYS_AT_NON_UC_BUFFER_SIZE_DEFAULT ? 0 : entry_num;
    for (index = 0; index < entry_num; index++)
    {
        cmd = DRV_IOR(DsIrmPortGuaranteedThrdProfileMc_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &ds));
        SetDsIrmPortGuaranteedThrdProfileMc(V, portGuaranteedThrd_f, &ds, SYS_AT_PORT_MIN_GUARANTEE);
        cmd = DRV_IOW(DsIrmPortGuaranteedThrdProfileMc_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &ds));
    }

    /* 8. default disable port limit check*/
    sal_memset(&ds, 0, sizeof(ds));
    SetDsIrmPortLimitedThrdProfileMc(V, g_0_portLimitedThrd_f, &ds, SYS_AT_LIMIT_MAX_THRD_MC_IRM);
    SetDsIrmPortLimitedThrdProfileMc(V, g_1_portLimitedThrd_f, &ds, SYS_AT_LIMIT_MAX_THRD_MC_IRM);
    SetDsIrmPortLimitedThrdProfileMc(V, g_2_portLimitedThrd_f, &ds, SYS_AT_LIMIT_MAX_THRD_MC_IRM);
    SetDsIrmPortLimitedThrdProfileMc(V, g_3_portLimitedThrd_f, &ds, SYS_AT_LIMIT_MAX_THRD_MC_IRM);
    sys_usw_ftm_query_table_entry_num(lchip, DsIrmPortLimitedThrdProfileMc_t, &entry_num);
    cmd = DRV_IOW(DsIrmPortLimitedThrdProfileMc_t, DRV_ENTRY_FLAG);
    for (index = 0; index < entry_num; index++)
    {
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &ds));
    }

    /* 9. default disable port Tc limit check*/
    sal_memset(&ds, 0, sizeof(ds));
    SetDsIrmPortTcLimitedThrdProfileMc(V, g_0_portTcLimitedThrd_f, &ds, SYS_AT_LIMIT_MAX_THRD_MC_IRM);
    SetDsIrmPortTcLimitedThrdProfileMc(V, g_1_portTcLimitedThrd_f, &ds, SYS_AT_LIMIT_MAX_THRD_MC_IRM);
    SetDsIrmPortTcLimitedThrdProfileMc(V, g_2_portTcLimitedThrd_f, &ds, SYS_AT_LIMIT_MAX_THRD_MC_IRM);
    SetDsIrmPortTcLimitedThrdProfileMc(V, g_3_portTcLimitedThrd_f, &ds, SYS_AT_LIMIT_MAX_THRD_MC_IRM);
    sys_usw_ftm_query_table_entry_num(lchip, DsIrmPortTcLimitedThrdProfileMc_t, &entry_num);
    cmd = DRV_IOW(DsIrmPortTcLimitedThrdProfileMc_t, DRV_ENTRY_FLAG);
    for (index = 0; index < entry_num; index++)
    {
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &ds));
    }

    /* 10. default disable port sc limit check*/
    sal_memset(&ds, 0, sizeof(ds));
    SetDsIrmPortScLimitedThrdProfileMc(V, g_0_portScLimitedThrd_f, &ds, SYS_AT_LIMIT_MAX_THRD_MC_IRM);
    SetDsIrmPortScLimitedThrdProfileMc(V, g_1_portScLimitedThrd_f, &ds, SYS_AT_LIMIT_MAX_THRD_MC_IRM);
    SetDsIrmPortScLimitedThrdProfileMc(V, g_2_portScLimitedThrd_f, &ds, SYS_AT_LIMIT_MAX_THRD_MC_IRM);
    SetDsIrmPortScLimitedThrdProfileMc(V, g_3_portScLimitedThrd_f, &ds, SYS_AT_LIMIT_MAX_THRD_MC_IRM);
    sys_usw_ftm_query_table_entry_num(lchip, DsIrmPortScLimitedThrdProfileMc_t, &entry_num);
    cmd = DRV_IOW(DsIrmPortScLimitedThrdProfileMc_t, DRV_ENTRY_FLAG);
    for (index = 0; index < entry_num; index++)
    {
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &ds));
    }
    return CTC_E_NONE;
}
STATIC int32
_sys_at_igs_uc_resrc_mgr_init(uint8 lchip, ctc_qos_global_cfg_t* p_cfg, uint32 min_pool_size)
{
    uint32 cmd                     = 0;
    uint32 field_val               = 0;
    uint16 channel                 = 0;
    uint16 index                   = 0;
    uint8 index1                   = 0;
    uint8 priority                 = 0;
    uint8 color                    = 0;
    uint8 step                     = 0;
    uint32 entry_num               = 0;
    uint32 pool_size[CTC_QOS_IGS_RESRC_POOL_MAX] = {0};
    uint32 total_pool_size = 0;
    ds_t ds;

    /*UC*/
    /* 1. Buffer assign, total buffer cell is alloced by user*/
    if (p_cfg->resrc_pool.igs_pool_mode == CTC_QOS_RESRC_POOL_DISABLE)
    {
        pool_size[CTC_QOS_IGS_RESRC_SC0_POOL]       = MCHIP_CAP(SYS_CAP_QOS_DROP_TOTAL_UC_POOL_SIZE) - 1280 - min_pool_size;
        pool_size[CTC_QOS_IGS_RESRC_MIN_POOL]       = min_pool_size;
        pool_size[CTC_QOS_IGS_RESRC_C2C_POOL]       = 0;
        pool_size[CTC_QOS_IGS_RESRC_ROUND_TRIP_POOL]= 1280;     /*headroom*/
        pool_size[CTC_QOS_IGS_RESRC_CONTROL_POOL]   = 0;
    }
    else if (p_cfg->resrc_pool.igs_pool_mode == CTC_QOS_RESRC_POOL_USER_DEFINE)
    {
        sal_memcpy(pool_size, p_cfg->resrc_pool.igs_pool_size, sizeof(pool_size));
    }
    else
    {
        return CTC_E_INVALID_PARAM;
    }

    total_pool_size = pool_size[CTC_QOS_IGS_RESRC_SC0_POOL] + pool_size[CTC_QOS_IGS_RESRC_SC1_POOL] + pool_size[CTC_QOS_IGS_RESRC_SC2_POOL] + pool_size[CTC_QOS_IGS_RESRC_SC3_POOL] +
                      pool_size[CTC_QOS_IGS_RESRC_MIN_POOL] + pool_size[CTC_QOS_IGS_RESRC_C2C_POOL] + pool_size[CTC_QOS_IGS_RESRC_ROUND_TRIP_POOL] + pool_size[CTC_QOS_IGS_RESRC_CONTROL_POOL];
    if (pool_size[CTC_QOS_IGS_RESRC_SC0_POOL] == 0 || total_pool_size > MCHIP_CAP(SYS_CAP_QOS_DROP_TOTAL_UC_POOL_SIZE))
    {
        return CTC_E_INVALID_PARAM;
    }
    total_pool_size = MCHIP_CAP(SYS_CAP_QOS_DROP_TOTAL_UC_POOL_SIZE);
    /* 2. enable ingress resource management*/
    cmd = DRV_IOR(IrmMiscCtlUc_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
    SetIrmMiscCtlUc(V, resourceCheckEn_f , &ds, 1);
    SetIrmMiscCtlUc(V, continuousPortUseScRemain_f , &ds, 1);
    SetIrmMiscCtlUc(V, continuousPortTcUseScRemain_f , &ds, 1);
    SetIrmMiscCtlUc(V, flowControlScEn_f , &ds, 1);
    SetIrmMiscCtlUc(V, flowControlUsePortCnt_f , &ds, 0);
    SetIrmMiscCtlUc(V, glbPortGuaranteedDis_f , &ds, 0);
    SetIrmMiscCtlUc(V, glbPortLimitedDis_f , &ds, 0);
    SetIrmMiscCtlUc(V, glbPortScGuaranteedDis_f , &ds, 0);
    SetIrmMiscCtlUc(V, glbPortScLimitedDis_f , &ds, 0);
    SetIrmMiscCtlUc(V, glbPortTcLimitedDis_f , &ds, 0);
    SetIrmMiscCtlUc(V, scExcludeGuarantee_f , &ds, 1);
    SetIrmMiscCtlUc(V, totalExcludeGuarantee_f , &ds, 1);
    SetIrmMiscCtlUc(V, guaranteedMode_f, &ds, 7);
    SetIrmMiscCtlUc(V, thrdPassMode_f, &ds, 7);
    SetIrmMiscCtlUc(V, headroomOpEn_f, &ds, 1);
    SetIrmMiscCtlUc(V, scRescMode_f , &ds, 0);
    cmd = DRV_IOW(IrmMiscCtlUc_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));

    cmd = DRV_IOR(ResrcMgmtCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
    if (0 == pool_size[CTC_QOS_IGS_RESRC_C2C_POOL])
    {
        SetResrcMgmtCtl(V, g_0_noCareC2cPacket_f, &ds, 1);
    }
    if (0 == pool_size[CTC_QOS_IGS_RESRC_CONTROL_POOL])
    {
        SetResrcMgmtCtl(V, g_0_noCareCriticalPacket_f, &ds, 1);
    }
    cmd = DRV_IOW(ResrcMgmtCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));


    /* 3. threshold config*/
    cmd = DRV_IOR(DsIrmMiscThrdUc_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
    SetDsIrmMiscThrdUc(V, c2cThrd_f, &ds, pool_size[CTC_QOS_IGS_RESRC_C2C_POOL]);
    SetDsIrmMiscThrdUc(V, criticalThrd_f, &ds, pool_size[CTC_QOS_IGS_RESRC_CONTROL_POOL]);
    SetDsIrmMiscThrdUc(V, totalThrd_f, &ds, total_pool_size);
    cmd = DRV_IOW(DsIrmMiscThrdUc_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));

    /*headroom thrd*/
    cmd = DRV_IOR(DsIrmHeadroomThrd_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
    SetDsIrmHeadroomThrd(V, headroomThrd_f, &ds, pool_size[CTC_QOS_IGS_RESRC_ROUND_TRIP_POOL]);
    cmd = DRV_IOW(DsIrmHeadroomThrd_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));

    /* 4. configure default pool threshold, only use one sc */
    cmd = DRV_IOR(DsIrmScThrdUc_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
    SetDsIrmScThrdUc(V, g_0_scEn_f, &ds, 1);
    SetDsIrmScThrdUc(V, g_0_scThrd_f, &ds, (pool_size[CTC_QOS_IGS_RESRC_SC0_POOL]+pool_size[CTC_QOS_IGS_RESRC_C2C_POOL]+pool_size[CTC_QOS_IGS_RESRC_CONTROL_POOL]));
    SetDsIrmScThrdUc(V, g_1_scEn_f, &ds, pool_size[CTC_QOS_IGS_RESRC_SC1_POOL] ? 1 : 0);
    SetDsIrmScThrdUc(V, g_1_scThrd_f, &ds, pool_size[CTC_QOS_IGS_RESRC_SC1_POOL]);
    SetDsIrmScThrdUc(V, g_2_scEn_f, &ds, pool_size[CTC_QOS_IGS_RESRC_SC2_POOL] ? 1 : 0);
    SetDsIrmScThrdUc(V, g_2_scThrd_f, &ds, pool_size[CTC_QOS_IGS_RESRC_SC2_POOL]);
    SetDsIrmScThrdUc(V, g_3_scEn_f, &ds, pool_size[CTC_QOS_IGS_RESRC_SC3_POOL] ? 1 : 0);
    SetDsIrmScThrdUc(V, g_3_scThrd_f, &ds, pool_size[CTC_QOS_IGS_RESRC_SC3_POOL]);
    cmd = DRV_IOW(DsIrmScThrdUc_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));

    /* 5. all priority mapped to tc priority/2 and sc 0 */
    for (channel = 0; channel < 512; channel++)
    {
        cmd = DRV_IOR(DsResrcMgmtRxPrioMapUc_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, channel, cmd, &ds));
        step = DsResrcMgmtRxPrioMapUc_g0_1_mappedSc_f - DsResrcMgmtRxPrioMapUc_g0_0_mappedSc_f;
        for (priority = 0; priority < 16; priority++)
        {
            SetDsResrcMgmtRxPrioMapUc(V, g0_0_mappedTc_f + priority * step, &ds, priority / 2);
            SetDsResrcMgmtRxPrioMapUc(V, g0_0_mappedSc_f + priority * step, &ds, 0);
        }
        step = DsResrcMgmtRxPrioMapUc_g1_1_dropPrecedence_f - DsResrcMgmtRxPrioMapUc_g1_0_dropPrecedence_f;
        for (color = 0; color < 4; color++)
        {
            field_val = (color + 3) % 4;
            SetDsResrcMgmtRxPrioMapUc(V, g1_0_dropPrecedence_f + color * step, &ds, field_val);
        }
        cmd = DRV_IOW(DsResrcMgmtRxPrioMapUc_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, channel, cmd, &ds));
    }

    /* 6. configure port minimum guarantee, default port Min = 80*/
    sys_usw_ftm_query_table_entry_num(lchip, DsIrmPortGuaranteedThrdProfileUc_t, &entry_num);
    for (index = 0; index < entry_num; index++)
    {
        cmd = DRV_IOR(DsIrmPortGuaranteedThrdProfileUc_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &ds));
        SetDsIrmPortGuaranteedThrdProfileUc(V, portGuaranteedThrd_f, &ds, SYS_AT_PORT_MIN_GUARANTEE);
        cmd = DRV_IOW(DsIrmPortGuaranteedThrdProfileUc_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &ds));
    }
    /* 7. disable port limited thrd check*/
    sal_memset(&ds, 0, sizeof(ds));
    SetDsIrmPortLimitedThrdProfileUc(V, g_0_portLimitedThrd_f, &ds, SYS_AT_LIMIT_MAX_THRD_UC);
    SetDsIrmPortLimitedThrdProfileUc(V, g_1_portLimitedThrd_f, &ds, SYS_AT_LIMIT_MAX_THRD_UC);
    SetDsIrmPortLimitedThrdProfileUc(V, g_2_portLimitedThrd_f, &ds, SYS_AT_LIMIT_MAX_THRD_UC);
    SetDsIrmPortLimitedThrdProfileUc(V, g_3_portLimitedThrd_f, &ds, SYS_AT_LIMIT_MAX_THRD_UC);
    cmd = DRV_IOW(DsIrmPortLimitedThrdProfileUc_t, DRV_ENTRY_FLAG);

    sys_usw_ftm_query_table_entry_num(lchip, DsIrmPortLimitedThrdProfileUc_t, &entry_num);
    for (index = 0; index < entry_num; index++)
    {
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &ds));
    }

    /* 8. disable portTc limited thrd check*/
    sal_memset(&ds, 0, sizeof(ds));
    SetDsIrmPortTcLimitedThrdProfileUc(V, g_0_portTcLimitedThrd_f, &ds, SYS_AT_LIMIT_MAX_THRD_UC);
    SetDsIrmPortTcLimitedThrdProfileUc(V, g_1_portTcLimitedThrd_f, &ds, SYS_AT_LIMIT_MAX_THRD_UC);
    SetDsIrmPortTcLimitedThrdProfileUc(V, g_2_portTcLimitedThrd_f, &ds, SYS_AT_LIMIT_MAX_THRD_UC);
    SetDsIrmPortTcLimitedThrdProfileUc(V, g_3_portTcLimitedThrd_f, &ds, SYS_AT_LIMIT_MAX_THRD_UC);
    cmd = DRV_IOW(DsIrmPortTcLimitedThrdProfileUc_t, DRV_ENTRY_FLAG);

    sys_usw_ftm_query_table_entry_num(lchip, DsIrmPortTcLimitedThrdProfileUc_t, &entry_num);
    for (index = 0; index < entry_num; index++)
    {
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &ds));
    }

    /*9. default pc/pfc thrd */
    sys_usw_ftm_query_table_entry_num(lchip, DsIrmPortFlowControlThrdProfile_t, &entry_num);
    step = DsIrmPortFlowControlThrdProfile_g_1_xoffThrd_f - DsIrmPortFlowControlThrdProfile_g_0_xoffThrd_f;
    for (index = 0; index < entry_num; index++)
    {
        cmd = DRV_IOR(DsIrmPortFlowControlThrdProfile_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &ds));
        for (index1 = 0; index1 < 8; index1++)
        {
            SetDsIrmPortFlowControlThrdProfile(V, g_0_xoffThrd_f + step * index1, &ds, 256 * (DRV_FROM_AT(lchip) ? 4 : 1));
            SetDsIrmPortFlowControlThrdProfile(V, g_0_xonThrd_f + step * index1, &ds, 224 * (DRV_FROM_AT(lchip) ? 4 : 1));

        }
        cmd = DRV_IOW(DsIrmPortFlowControlThrdProfile_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &ds));
    }

    /*default disable port sc limit check*/
    sal_memset(&ds, 0, sizeof(ds));
    SetDsIrmPortScLimitedThrdProfileUc(V, g_0_portScLimitedThrd_f, &ds, SYS_AT_LIMIT_MAX_THRD_UC);
    SetDsIrmPortScLimitedThrdProfileUc(V, g_1_portScLimitedThrd_f, &ds, SYS_AT_LIMIT_MAX_THRD_UC);
    SetDsIrmPortScLimitedThrdProfileUc(V, g_2_portScLimitedThrd_f, &ds, SYS_AT_LIMIT_MAX_THRD_UC);
    SetDsIrmPortScLimitedThrdProfileUc(V, g_3_portScLimitedThrd_f, &ds, SYS_AT_LIMIT_MAX_THRD_UC);
    sys_usw_ftm_query_table_entry_num(lchip, DsIrmPortScLimitedThrdProfileUc_t, &entry_num);
    cmd = DRV_IOW(DsIrmPortScLimitedThrdProfileUc_t, DRV_ENTRY_FLAG);
    for (index = 0; index < entry_num; index++)
    {
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &ds));
    }
    return CTC_E_NONE;
}

STATIC int32
_sys_at_mrm_resrc_mgr_init(uint8 lchip, ctc_qos_global_cfg_t* p_cfg)
{
    uint32 cmd = 0;
    uint32 entry_num = 0;
    uint8 loop = 0;
    uint8 step= 0;
    uint8 mapped_tc[16] = {0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5};
    ds_t ds;

    cmd = DRV_IOR(ResrcMgmtTxPrioMapMc_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
    step = ResrcMgmtTxPrioMapMc_g0_1_mappedTc_f - ResrcMgmtTxPrioMapMc_g0_0_mappedTc_f;
    for (loop = 0; loop < 16; loop++)/*priority*/
    {
        SetResrcMgmtTxPrioMapMc(V, g0_0_mappedTc_f + loop * step, &ds, mapped_tc[loop]);
    }
    step = ResrcMgmtTxPrioMapMc_g1_1_dropPrecedence_f - ResrcMgmtTxPrioMapMc_g1_0_dropPrecedence_f;
    for (loop = 0; loop < 4; loop++)/*color*/
    {
        SetResrcMgmtTxPrioMapMc(V, g1_0_dropPrecedence_f + loop * step, &ds, (loop + 3) % 4);
    }
    cmd = DRV_IOW(ResrcMgmtTxPrioMapMc_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));

    cmd = DRV_IOR(MrmMiscCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
    SetMrmMiscCtl(V, glbGuaranteedDis_f, &ds, 0);
    SetMrmMiscCtl(V, glbLimitedDis_f, &ds, 0);
    SetMrmMiscCtl(V, resourceCheckEn_f, &ds, 1);
    cmd = DRV_IOW(MrmMiscCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));

    cmd = DRV_IOR(DsMrmMiscThrd_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
    SetDsMrmMiscThrd(V, totalThrd_f, &ds, MCHIP_CAP(SYS_CAP_QOS_DROP_MRM_TOTAL_POOL_SIZE));
    cmd = DRV_IOW(DsMrmMiscThrd_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));

    sal_memset(ds, 0, sizeof(ds));
    sys_usw_ftm_query_table_entry_num(lchip, DsMrmQueueThrd_t, &entry_num);
    SetDsMrmQueueThrd(V, g_0_limitedAutoEn_f , &ds, 1);
    SetDsMrmQueueThrd(V, g_1_limitedAutoEn_f , &ds, 1);
    SetDsMrmQueueThrd(V, g_2_limitedAutoEn_f , &ds, 1);
    SetDsMrmQueueThrd(V, g_3_limitedAutoEn_f , &ds, 1);
    SetDsMrmQueueThrd(V, guaranteedThrd_f , &ds, 455);
    cmd = DRV_IOW(DsMrmQueueThrd_t, DRV_ENTRY_FLAG);
    for(loop = 0; loop < entry_num; loop++)
    {
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, loop, cmd, &ds));
    }

    return CTC_E_NONE;
}

STATIC uint32
_sys_at_resrc_get_speed_guarantee(sys_port_info_t* port_info)
{
    uint32 guaranteed_thrd = 0;

    switch (port_info->speed_mode)
    {
        case CTC_PORT_SPEED_1G:
        case CTC_PORT_SPEED_2G5:
        case CTC_PORT_SPEED_5G:
        case CTC_PORT_SPEED_10G:
        case CTC_PORT_SPEED_20G:
        case CTC_PORT_SPEED_25G:
        case CTC_PORT_SPEED_40G:
        case CTC_PORT_SPEED_50G:
        case CTC_PORT_SPEED_100G:
            guaranteed_thrd = SYS_AT_PORT_MIN_GUARANTEE;
            break;
        case CTC_PORT_SPEED_200G:
            guaranteed_thrd = 110;
            break;
        case CTC_PORT_SPEED_400G:
        case CTC_PORT_SPEED_800G:
            guaranteed_thrd = 220;
            break;
        default:
            guaranteed_thrd = SYS_AT_PORT_MIN_GUARANTEE;
            break;
    }
    return guaranteed_thrd;
}

STATIC int32
_sys_at_resrc_port_guarantee_init(uint8 lchip)
{
    sys_port_info_t port_info = {0};
    uint32 guarantee = 0;
    uint32 cmd = 0;
    uint16 lport = 0;

    for (lport = 0; lport < MCHIP_CAP(SYS_CAP_PER_SLICE_PORT_NUM); lport++)
    {
        CTC_ERROR_RETURN(sys_usw_port_api_get_com_info(lchip, lport, 0, &port_info));
        if (!(SYS_DMPS_NETWORK_PORT == port_info.port_type || SYS_DMPS_CPUMAC_NETWORK_PORT == port_info.port_type || SYS_DMPS_CPU_MAC_PORT == port_info.port_type))
        {
            continue;
        }
        guarantee = _sys_at_resrc_get_speed_guarantee(&port_info);

        SYS_QOS_LCHIP_CONVERT(lchip, port_info.pp_id);
        cmd = DRV_IOW(DsIrmPortGuaranteedThrdProfileUc_t, DsIrmPortGuaranteedThrdProfileUc_portGuaranteedThrd_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, port_info.sub_chan_id, DRV_CMD_DP_EN(cmd, port_info.dp_id), &guarantee));
        cmd = DRV_IOW(DsIrmPortGuaranteedThrdProfileMc_t, DsIrmPortGuaranteedThrdProfileMc_portGuaranteedThrd_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, port_info.sub_chan_id, DRV_CMD_DP_EN(cmd, port_info.dp_id), &guarantee));

        cmd = DRV_IOW(DsErmPortThrdProfileUc_t, DsErmPortThrdProfileUc_portGuaranteedThrd_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, port_info.sub_chan_id, DRV_CMD_DP_EN(cmd, port_info.dp_id), &guarantee));
        cmd = DRV_IOW(DsErmPortGuaranteedThrdProfileMc_t, DsErmPortGuaranteedThrdProfileMc_g_0_portGuaranteedThrd_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, SYS_AT_QOS_ENCOD_CORE_CHAN(port_info.sub_chan_id, port_info.pp_id, port_info.dp_id), DRV_CMD_DP_EN(cmd, port_info.dp_id), &guarantee));
    }

    return CTC_E_NONE;
}

int32
sys_at_resrc_get_min_pool_size(uint8 lchip, uint32* min_pool_size)
{
    uint16 lport = 0;
    sys_port_info_t port_info = {0};

    *min_pool_size = 0;

    for (lport = 0; lport < MCHIP_CAP(SYS_CAP_PER_SLICE_PORT_NUM); lport++)
    {
        CTC_ERROR_RETURN(sys_usw_port_api_get_com_info(lchip, lport, 0, &port_info));
        if (!(SYS_DMPS_NETWORK_PORT == port_info.port_type || SYS_DMPS_CPUMAC_NETWORK_PORT == port_info.port_type || SYS_DMPS_CPU_MAC_PORT == port_info.port_type))
        {
            continue;
        }
        *min_pool_size += _sys_at_resrc_get_speed_guarantee(&port_info);
    }

    /*(4*2*2 - 2)*80, per core except cpu mac chan but misc chan's guarantee size*/
    *min_pool_size += (4*2*2-2) * 80;

    return CTC_E_NONE;
}

int32
sys_at_qos_resrc_mgr_init(uint8 lchip, void *p_glb_parm)
{
    uint32 cmd = 0;
    uint32 min_pool_size = 0;
    uint16 index  = 0;
    uint8 step = 0;
    int32 ret =0;
    ctc_qos_global_cfg_t *p_glb_cfg = (ctc_qos_global_cfg_t *)p_glb_parm;
    ctc_qos_resrc_pool_cfg_t *resrc_pool;
    DsEpeHeaderEditChanAqmThrd_m aqm_port_thrd;
    ErmPortStallStateScanCtl_m erm_port_stall_scan;
    AqmPortScanCtl_m aqm_port_ctl;
    ds_t ds;

    resrc_pool = mem_malloc(MEM_QUEUE_MODULE, sizeof(ctc_qos_resrc_pool_cfg_t));
    if (NULL == resrc_pool)
    {
        return CTC_E_NO_MEMORY;

    }
    sal_memset(&erm_port_stall_scan, 0, sizeof(ErmPortStallStateScanCtl_m));
    sal_memset(&aqm_port_thrd, 0, sizeof(aqm_port_thrd));
    sal_memset(resrc_pool, 0, sizeof(ctc_qos_resrc_pool_cfg_t));

    CTC_ERROR_GOTO(sys_at_resrc_get_min_pool_size(lchip, &min_pool_size),ret, free_mem);

    if ( !sal_memcmp(&(((ctc_qos_global_cfg_t *)p_glb_cfg)->resrc_pool), resrc_pool, sizeof(ctc_qos_resrc_pool_cfg_t))
        || !sal_memcmp(&(((ctc_qos_global_cfg_t *)p_glb_cfg)->resrc_pool2), resrc_pool, sizeof(ctc_qos_resrc_pool_cfg_t)) )
    {
        p_glb_cfg->resrc_pool.igs_pool_mode = CTC_QOS_RESRC_POOL_DISABLE;
        p_glb_cfg->resrc_pool.egs_pool_mode = CTC_QOS_RESRC_POOL_USER_DEFINE;
        p_glb_cfg->resrc_pool.egs_pool_size[CTC_QOS_EGS_RESRC_SC0_POOL]  = MCHIP_CAP(SYS_CAP_QOS_DROP_TOTAL_UC_POOL_SIZE) - 2048 - min_pool_size;
        p_glb_cfg->resrc_pool.egs_pool_size[CTC_QOS_EGS_RESRC_SC1_POOL] = 0;
        p_glb_cfg->resrc_pool.egs_pool_size[CTC_QOS_EGS_RESRC_SC3_POOL]  = 1024;
        p_glb_cfg->resrc_pool.egs_pool_size[CTC_QOS_EGS_RESRC_C2C_POOL]  = 1024;

        p_glb_cfg->resrc_pool2.igs_pool_mode = CTC_QOS_RESRC_POOL_DISABLE;
        p_glb_cfg->resrc_pool2.egs_pool_mode = CTC_QOS_RESRC_POOL_USER_DEFINE;
        p_glb_cfg->resrc_pool2.egs_pool_size[CTC_QOS_EGS_RESRC_SC0_POOL]  = MCHIP_CAP(SYS_CAP_QOS_DROP_TOTAL_NON_UC_POOL_SIZE) - 2048 - 4000;
        p_glb_cfg->resrc_pool2.egs_pool_size[CTC_QOS_EGS_RESRC_SC0_POOL]  -= (p_glb_cfg->resrc_pool2.egs_pool_size[CTC_QOS_EGS_RESRC_SC0_POOL] < min_pool_size ? 0 : min_pool_size);
        p_glb_cfg->resrc_pool2.egs_pool_size[CTC_QOS_EGS_RESRC_SC3_POOL]  = 1024;
        p_glb_cfg->resrc_pool2.egs_pool_size[CTC_QOS_EGS_RESRC_C2C_POOL]  = 1024;
    }

    CTC_ERROR_GOTO(_sys_at_igs_uc_resrc_mgr_init(lchip, p_glb_cfg, min_pool_size),ret, free_mem);
    CTC_ERROR_GOTO(_sys_at_igs_mc_resrc_mgr_init(lchip, p_glb_cfg, min_pool_size),ret, free_mem);
    CTC_ERROR_GOTO(_sys_at_egs_uc_resrc_mgr_init(lchip, p_glb_cfg, min_pool_size),ret, free_mem);
    CTC_ERROR_GOTO(_sys_at_egs_mc_resrc_mgr_init(lchip, p_glb_cfg, min_pool_size),ret, free_mem);
    CTC_ERROR_GOTO(_sys_at_mrm_resrc_mgr_init(lchip, p_glb_cfg),ret, free_mem);
    CTC_ERROR_GOTO(_sys_at_resrc_port_guarantee_init(lchip),ret, free_mem);

    /*diable  port aqm, mark ecn base on rate*/
    // sys_usw_ftm_query_table_entry_num(lchip, DsEpeHeaderEditChanAqmThrd_t, &entry_num);
    // for (index = 0; index < entry_num; index++)
    // {
    //     cmd = DRV_IOR(DsEpeHeaderEditChanAqmThrd_t, DRV_ENTRY_FLAG);
    //     CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &aqm_port_thrd));
    //     SetDsEpeHeaderEditChanAqmThrd(V, aqmPortThrdHigh_f, &aqm_port_thrd, 0);
    //     SetDsEpeHeaderEditChanAqmThrd(V, aqmPortThrdLow_f, &aqm_port_thrd, 0xFFFFFFFF);
    //     cmd = DRV_IOW(DsEpeHeaderEditChanAqmThrd_t, DRV_ENTRY_FLAG);
    //     CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &aqm_port_thrd));
    // }

    // sal_memset(&ds, 0, sizeof(ds));
    // SetDsErmPortTcStallThrdProfile(V, g_0_xoffThrd_f, &ds, 0x3FFFF);
    // SetDsErmPortTcStallThrdProfile(V, g_0_xonThrd_f, &ds, 0x3FFFF);
    // SetDsErmPortTcStallThrdProfile(V, g_1_xoffThrd_f, &ds, 0x3FFFF);
    // SetDsErmPortTcStallThrdProfile(V, g_1_xonThrd_f, &ds, 0x3FFFF);
    // SetDsErmPortTcStallThrdProfile(V, g_2_xoffThrd_f, &ds, 0x3FFFF);
    // SetDsErmPortTcStallThrdProfile(V, g_2_xonThrd_f, &ds, 0x3FFFF);
    // cmd = DRV_IOW(DsErmPortTcStallThrdProfile_t, DRV_ENTRY_FLAG);
    // sys_usw_ftm_query_table_entry_num(lchip, DsErmPortTcStallThrdProfile_t, &entry_num);
    // for (index = 0; index < entry_num / 2; index++)
    // {
    //     CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &ds));
    // }
    sal_memset(&ds, 0, sizeof(ds));
    step = MrmStallThrd_g_1_xonThrd0_f - MrmStallThrd_g_0_xonThrd0_f;
    for (index = 0; index < 8; index++)
    {
        SetMrmStallThrd(V, g_0_xonThrd0_f  + step * index, &ds, 0xFFFF);
        SetMrmStallThrd(V, g_0_xonThrd1_f  + step * index, &ds, 0xFFFF);
        SetMrmStallThrd(V, g_0_xonThrd2_f  + step * index, &ds, 0xFFFF);
        SetMrmStallThrd(V, g_0_xoffThrd0_f + step * index, &ds, 0xFFFF);
        SetMrmStallThrd(V, g_0_xoffThrd1_f + step * index, &ds, 0xFFFF);
        SetMrmStallThrd(V, g_0_xoffThrd2_f + step * index, &ds, 0xFFFF);
    }
    cmd = DRV_IOW(MrmStallThrd_t, DRV_ENTRY_FLAG);
    CTC_ERROR_GOTO(DRV_IOCTL(lchip, 0, cmd, &ds),ret, free_mem);

    SetErmPortStallStateScanCtl(V, portStallStateScanEn_f, &erm_port_stall_scan, 1);
    SetErmPortStallStateScanCtl(V, portStallStateScanInterval_f, &erm_port_stall_scan, 100);
    SetErmPortStallStateScanCtl(V, portStallStateScanSliceEnVec_f, &erm_port_stall_scan, SYS_PP_BMP(lchip));
    cmd = DRV_IOW(ErmPortStallStateScanCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_GOTO(DRV_IOCTL(lchip, 0, cmd, &erm_port_stall_scan),ret, free_mem);

    sal_memset(&ds, 0, sizeof(ds));
    SetMrmStallStateScanCtl(V, mrmStallStateScanEn_f, &ds, 1);
    SetMrmStallStateScanCtl(V, mrmStallStateScanInterval_f, &ds, 100);
    cmd = DRV_IOW(MrmStallStateScanCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_GOTO(DRV_IOCTL(lchip, 0, cmd, &ds),ret, free_mem);

    sal_memset(&aqm_port_ctl, 0, sizeof(AqmPortScanCtl_m));
    SetAqmPortScanCtl(V, aqmPortScanEn_f, &aqm_port_ctl, 1);
    SetAqmPortScanCtl(V, aqmPortScanInterval_f, &aqm_port_ctl, 10);
    cmd = DRV_IOW(AqmPortScanCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_GOTO(DRV_IOCTL(lchip, 0, cmd, &aqm_port_ctl),ret, free_mem);

free_mem:
	mem_free(resrc_pool);
    return CTC_E_NONE;

}

int32
sys_at_queue_drop_init_profile(uint8 lchip, ctc_qos_global_cfg_t* p_cfg)
{
    int32 ret = CTC_E_NONE;
    sys_usw_opf_t opf;
    uint32 que_drop_wred_profile_num = 0;
    uint32 start_offset = 0;
    uint8 pp_num = 0;
    uint8 index = 0;
    ctc_spool_t spool;

    sal_memset(&opf, 0, sizeof(sys_usw_opf_t));
    pp_num = SYS_PP_NUM(lchip);
    /* init drop profile spool table */
    sys_usw_ftm_query_table_entry_num(lchip, DsAqmQueueThrdProfile_t, &que_drop_wred_profile_num);
    /*peer dp table, profile num should consider core num */
    que_drop_wred_profile_num /= drv_vchip_get_core_num(lchip);

    /*create queue drop wred profile spool*/
    sal_memset(&spool, 0, sizeof(ctc_spool_t));
    spool.lchip = lchip;
    spool.block_num = 1;
    spool.block_size = 1;
    spool.max_count = (que_drop_wred_profile_num - 1) * pp_num * 2; /*per dp*/
    spool.user_data_size = sizeof(sys_queue_drop_wred_profile_t);
    spool.spool_key = (hash_key_fn)_sys_usw_queue_drop_wred_hash_make_profile;
    spool.spool_cmp = (hash_cmp_fn)_sys_usw_queue_drop_wred_hash_cmp_profile;
    spool.spool_alloc = (spool_alloc_fn)_sys_usw_queue_drop_wred_alloc_profileId;
    spool.spool_free = (spool_free_fn)_sys_usw_queue_drop_wred_free_profileId;
    p_usw_queue_master[lchip]->p_drop_wred_profile_pool = ctc_spool_create(&spool);
    if (NULL == p_usw_queue_master[lchip]->p_drop_wred_profile_pool)
    {
        return CTC_E_NO_MEMORY;
    }

    /*init queue drop wred profile opf*/
    CTC_ERROR_GOTO(sys_usw_opf_init(lchip, &p_usw_queue_master[lchip]->opf_type_queue_drop_wred,
                                                                    pp_num * 2, "opf-queue-drop-wred"), ret, error0);

    opf.pool_type = p_usw_queue_master[lchip]->opf_type_queue_drop_wred;
    start_offset = 1; /*profile 0 mean disable*/
    for (index = 0; index < pp_num * 2; index++)
    {
        opf.pool_index = index; /*dp_id*/
        CTC_ERROR_GOTO(sys_usw_opf_init_offset(lchip, &opf, start_offset, (que_drop_wred_profile_num - 1)),
                       ret, error1);
    }

    return ret;

error1:
    sys_usw_opf_deinit(lchip, p_usw_queue_master[lchip]->opf_type_queue_drop_wred);
error0:
    ctc_spool_free(p_usw_queue_master[lchip]->p_drop_wred_profile_pool);
    p_usw_queue_master[lchip]->p_drop_wred_profile_pool = NULL;
    return ret;
}
int32
sys_at_queue_drop_deinit_profile(uint8 lchip)
{
    uint16 chan_id = 0;
    uint8 prio = 0;

    sys_usw_opf_deinit(lchip, p_usw_queue_master[lchip]->opf_type_queue_drop_wred);
    ctc_spool_free(p_usw_queue_master[lchip]->p_drop_wred_profile_pool);
    p_usw_queue_master[lchip]->p_drop_wred_profile_pool = NULL;

    for (; chan_id < SYS_MAX_CHANNEL_NUM; chan_id++)
    {
        mem_free(p_usw_queue_master[lchip]->p_fc_profile[chan_id]);
        for (prio = 0; prio < SYS_PRIO_CLASS_NUM; prio++)
        {
            mem_free(p_usw_queue_master[lchip]->p_pfc_profile[chan_id][prio]);
        }
    }
    return CTC_E_NONE;
}

STATIC int32
_sys_at_queue_drop_add_wred_profile(uint8 lchip, ctc_qos_drop_t* que_drop, sys_queue_node_t* p_sys_queue)
{
    uint32 cmd = 0;
    uint32 index = 0;
    uint8 step = 0;
    uint8 step_1 = 0;
    uint8 dp = 0;
    uint8 ofst = 0;
    uint8 q_ofst = 0;
    uint8 type = 0;
    sys_queue_drop_wred_profile_t  sys_wred_profile_old;
    sys_queue_drop_wred_profile_t  sys_wred_profile_new;
    sys_queue_drop_wred_profile_t* p_sys_wred_profile_get = NULL;
    DsErmAqmQueueThrdProfile_m ds_old;
    DsErmAqmQueueThrdProfile_m ds_new;
    DsErmAqmQueueThrdQuantProfile_m erm_aqm_thrd_profile;
    DsAqmQueueThrdProfileId_m aqm_que_thrd;
    DsAqmQueueCfg_m aqm_que_cfg;
    uint32 max_len_range[CTC_DROP_PREC_NUM] = {que_drop->drop.max_th[0], que_drop->drop.max_th[1], que_drop->drop.max_th[2], que_drop->drop.max_th[3]};
    uint32 min_len_range[CTC_DROP_PREC_NUM] = {que_drop->drop.min_th[0], que_drop->drop.min_th[1], que_drop->drop.min_th[2], que_drop->drop.min_th[3]};
    uint8  drop_prob[CTC_DROP_PREC_NUM]     = {que_drop->drop.drop_prob[0], que_drop->drop.drop_prob[1], que_drop->drop.drop_prob[2], que_drop->drop.drop_prob[3]};

    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    if (SYS_QUEUE_TYPE_EXCP == p_sys_queue->type || SYS_QUEUE_TYPE_EXCP_UC == p_sys_queue->type)
    {
        return CTC_E_NOT_SUPPORT;
    }

    ofst = SYS_AT_COS_SUB_NODE_OFST(p_sys_queue, que_drop->queue.class_prio);
    type = p_sys_queue->node[ofst].type;
    if (SYS_QUE_OFST_UC != type)
    {
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "Only UcQueue support wred!\n");
        return CTC_E_NOT_SUPPORT;
    }

    sal_memset(&erm_aqm_thrd_profile, 0, sizeof(erm_aqm_thrd_profile));
    sal_memset(&sys_wred_profile_new, 0, sizeof(sys_wred_profile_new));
    sal_memset(&sys_wred_profile_old, 0, sizeof(sys_wred_profile_old));
    sal_memset(&ds_old, 0, sizeof(ds_old));
    sal_memset(&ds_new, 0, sizeof(ds_new));

    /*old profile*/
    cmd = DRV_IOR(DsErmAqmQueueThrdProfile_t, DRV_ENTRY_FLAG);
    DRV_IOCTL(lchip, p_sys_queue->node[ofst].drop_wred_profile_id, DRV_CMD_DP_EN(cmd, p_sys_queue->dp_id), &ds_old);
    sys_wred_profile_old.profile_id = p_sys_queue->node[ofst].drop_wred_profile_id;
    sys_wred_profile_old.lchip = lchip;
    sys_wred_profile_old.p_ds = &ds_old;
    sys_wred_profile_old.dp_id = p_sys_queue->pp_id * 2 + p_sys_queue->dp_id;

    /*new profile*/
    /*AT DsAqmQueueThrdProfile -> DsErmAqmQueueThrdProfile, change tbl name in drv*/
    step = DsErmAqmQueueThrdQuantProfile_g_1_wredAvgMaxLen_f - DsErmAqmQueueThrdQuantProfile_g_0_wredAvgMaxLen_f;
    for (dp = 0; dp < CTC_DROP_PREC_NUM; dp++)
    {
        SetDsErmAqmQueueThrdProfile(V, g_0_wredAvgMaxLen_f + step*dp, &ds_new, max_len_range[dp] / 8);
        SetDsErmAqmQueueThrdProfile(V, g_0_wredAvgMinLen_f + step*dp, &ds_new, min_len_range[dp] / 8);
        SetDsErmAqmQueueThrdProfile(V, g_0_wredProbFactor_f + step*dp, &ds_new, drop_prob[dp] * 127 / 100);
    }
    sys_wred_profile_new.lchip = lchip;
    sys_wred_profile_new.p_ds = &ds_new;
    sys_wred_profile_new.dp_id = p_sys_queue->pp_id * 2 + p_sys_queue->dp_id;

    CTC_ERROR_RETURN(_sys_usw_queue_drop_wred_profile_add_spool(lchip, &sys_wred_profile_old, &sys_wred_profile_new, &p_sys_wred_profile_get));
    p_sys_queue->node[ofst].drop_wred_profile_id = p_sys_wred_profile_get->profile_id;

    /*add to asic*/
    SYS_QOS_LCHIP_CONVERT(lchip, p_sys_queue->pp_id);
    cmd = DRV_IOW(DsErmAqmQueueThrdProfile_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_sys_wred_profile_get->profile_id, DRV_CMD_DP_EN(cmd, p_sys_queue->dp_id), sys_wred_profile_new.p_ds));

    /*prob quantification*/
    step = DsErmAqmQueueThrdQuantProfile_g_1_wredAvgMaxLen_f - DsErmAqmQueueThrdQuantProfile_g_0_wredAvgMaxLen_f;
    step_1 = DsErmAqmQueueThrdQuantProfile_g_7_wredAvgMaxLen_f - DsErmAqmQueueThrdQuantProfile_g_0_wredAvgMaxLen_f;
    for (dp = 0; dp < CTC_DROP_PREC_NUM; dp++)
    {
        /*AT DsAqmQueueThrdQuantProfile -> DsErmAqmQueueThrdQuantProfile, change tbl name in drv*/
        for(index = 0; index < 7; index++)
        {
            SetDsErmAqmQueueThrdQuantProfile(V, g_0_wredAvgMaxLen_f + step*index + step_1*dp, &erm_aqm_thrd_profile, (min_len_range[dp] + ((max_len_range[dp] - min_len_range[dp]) / 8)*(index + 1)) / 8);
            SetDsErmAqmQueueThrdQuantProfile(V, g_0_wredProbFactor_f + step*index + step_1*dp, &erm_aqm_thrd_profile, (drop_prob[dp] * 127 / 100 / 8)*(index + 1));
        }
    }
    cmd = DRV_IOW(DsErmAqmQueueThrdQuantProfile_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_sys_wred_profile_get->profile_id, DRV_CMD_DP_EN(cmd, p_sys_queue->dp_id), &erm_aqm_thrd_profile));

    q_ofst = p_sys_queue->node[ofst].ofst;
    step = DsAqmQueueCfg_g_1_ewmaWeightFactor_f - DsAqmQueueCfg_g_0_ewmaWeightFactor_f;
    index = SYS_AT_QOS_ENCOD_DP_QUE_UC(p_sys_queue->sub_chan, q_ofst);
    cmd = DRV_IOR(DsAqmQueueThrdProfileId_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_DP_EN(cmd, p_sys_queue->dp_id), &aqm_que_thrd));
    SetDsAqmQueueThrdProfileId(V, aqmThrdProfileId_f, &aqm_que_thrd, p_sys_queue->node[ofst].drop_wred_profile_id);
    cmd = DRV_IOW(DsAqmQueueThrdProfileId_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_DP_EN(cmd, p_sys_queue->dp_id), &aqm_que_thrd));

    cmd = DRV_IOR(DsAqmQueueCfg_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index >> 2, DRV_CMD_DP_EN(cmd, p_sys_queue->dp_id), &aqm_que_cfg));
    SetDsAqmQueueCfg(V, g_0_ewmaWeightFactor_f + step*(index & 0x3), &aqm_que_cfg, que_drop->drop.weight ? que_drop->drop.weight : 1);
    cmd = DRV_IOW(DsAqmQueueCfg_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index >> 2, DRV_CMD_DP_EN(cmd, p_sys_queue->dp_id), &aqm_que_cfg));

    return CTC_E_NONE;
}

STATIC int32
_sys_at_queue_drop_get_wred_profile(uint8 lchip, ctc_qos_drop_t* que_drop, sys_queue_node_t* p_sys_queue)
{
    DsErmAqmQueueThrdQuantProfile_m erm_aqm_thrd_profile;
    DsAqmQueueCfg_m aqm_que_cfg;
    uint32 cmd = 0;
    uint32 field_val = 0;
    uint32 index = 0;
    uint8 step = 0;
    uint8 ofst = 0;

    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    if (SYS_QUEUE_TYPE_EXCP == p_sys_queue->type || SYS_QUEUE_TYPE_EXCP_UC == p_sys_queue->type)
    {
        return CTC_E_NOT_SUPPORT;
    }

    ofst = SYS_AT_COS_SUB_NODE_OFST(p_sys_queue, que_drop->queue.class_prio);
    if (SYS_QUE_OFST_UC != p_sys_queue->node[ofst].type)
    {
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "Only UcQueue support wred!\n");
        return CTC_E_NOT_SUPPORT;
    }

    sal_memset(&erm_aqm_thrd_profile, 0, sizeof(erm_aqm_thrd_profile));
    sal_memset(&aqm_que_cfg, 0, sizeof(aqm_que_cfg));

    index = p_sys_queue->node[ofst].drop_wred_profile_id;
    cmd = DRV_IOR(DsErmAqmQueueThrdProfile_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_DP_EN(cmd, p_sys_queue->dp_id), &erm_aqm_thrd_profile));
    que_drop->drop.max_th[0] = GetDsErmAqmQueueThrdProfile(V, g_0_wredAvgMaxLen_f, &erm_aqm_thrd_profile) * 8;
    que_drop->drop.max_th[1] = GetDsErmAqmQueueThrdProfile(V, g_1_wredAvgMaxLen_f, &erm_aqm_thrd_profile) * 8;
    que_drop->drop.max_th[2] = GetDsErmAqmQueueThrdProfile(V, g_2_wredAvgMaxLen_f, &erm_aqm_thrd_profile) * 8;
    que_drop->drop.max_th[3] = GetDsErmAqmQueueThrdProfile(V, g_3_wredAvgMaxLen_f, &erm_aqm_thrd_profile) * 8;
    que_drop->drop.min_th[0] = GetDsErmAqmQueueThrdProfile(V, g_0_wredAvgMinLen_f, &erm_aqm_thrd_profile) * 8;
    que_drop->drop.min_th[1] = GetDsErmAqmQueueThrdProfile(V, g_1_wredAvgMinLen_f, &erm_aqm_thrd_profile) * 8;
    que_drop->drop.min_th[2] = GetDsErmAqmQueueThrdProfile(V, g_2_wredAvgMinLen_f, &erm_aqm_thrd_profile) * 8;
    que_drop->drop.min_th[3] = GetDsErmAqmQueueThrdProfile(V, g_3_wredAvgMinLen_f, &erm_aqm_thrd_profile) * 8;
    field_val = GetDsErmAqmQueueThrdProfile(V, g_0_wredProbFactor_f, &erm_aqm_thrd_profile) * 100;
    que_drop->drop.drop_prob[0] =  (field_val % 127) ? (field_val / 127 + 1) : field_val / 127;
    field_val = GetDsErmAqmQueueThrdProfile(V, g_1_wredProbFactor_f, &erm_aqm_thrd_profile) * 100;
    que_drop->drop.drop_prob[1] = (field_val % 127) ? (field_val / 127 + 1) : field_val / 127;
    field_val = GetDsErmAqmQueueThrdProfile(V, g_2_wredProbFactor_f, &erm_aqm_thrd_profile) * 100;
    que_drop->drop.drop_prob[2] = (field_val % 127) ? (field_val / 127 + 1) : field_val / 127;
    field_val = GetDsErmAqmQueueThrdProfile(V, g_3_wredProbFactor_f, &erm_aqm_thrd_profile) * 100;
    que_drop->drop.drop_prob[3] = (field_val % 127) ? (field_val / 127 + 1) : field_val / 127;

    index = SYS_AT_QOS_ENCOD_DP_QUE_UC(p_sys_queue->sub_chan, p_sys_queue->node[ofst].ofst);
    cmd = DRV_IOR(DsAqmQueueCfg_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index >> 2, DRV_CMD_DP_EN(cmd, p_sys_queue->dp_id), &aqm_que_cfg));
    que_drop->drop.weight = GetDsAqmQueueCfg(V, g_0_ewmaWeightFactor_f + step*(index & 0x3), &aqm_que_cfg);

    return CTC_E_NONE;
}

STATIC int32
_sys_at_queue_drop_remove_wred_profile(uint8 lchip, ctc_qos_drop_t* que_drop, sys_queue_node_t* p_sys_queue)
{
    uint32 cmd = 0;
    uint32 index = 0;
    uint8  ofst = 0;
    DsAqmQueueThrdProfileId_m aqm_que_thrd;
    DsErmAqmQueueThrdProfile_m ds_old;
    sys_queue_drop_wred_profile_t sys_wred_profile_old;

    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    CTC_PTR_VALID_CHECK(p_sys_queue);

    ofst = SYS_AT_COS_SUB_NODE_OFST(p_sys_queue, que_drop->queue.class_prio);

    if(!p_sys_queue->node[ofst].drop_wred_profile_id)
    {
        return CTC_E_NONE;
    }

    sal_memset(&sys_wred_profile_old, 0, sizeof(sys_wred_profile_old));
    cmd = DRV_IOR(DsErmAqmQueueThrdProfile_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_sys_queue->node[ofst].drop_wred_profile_id, DRV_CMD_DP_EN(cmd, p_sys_queue->dp_id), &ds_old));
    sys_wred_profile_old.profile_id = p_sys_queue->node[ofst].drop_wred_profile_id;
    sys_wred_profile_old.lchip = lchip;
    sys_wred_profile_old.dp_id = p_sys_queue->pp_id * 2 + p_sys_queue->dp_id;
    sys_wred_profile_old.p_ds = &ds_old;

    CTC_ERROR_RETURN(ctc_spool_remove(p_usw_queue_master[lchip]->p_drop_wred_profile_pool, &sys_wred_profile_old, NULL));
    p_sys_queue->node[ofst].drop_wred_profile_id = 0;

    SYS_QOS_LCHIP_CONVERT(lchip, p_sys_queue->pp_id);
    index = SYS_AT_QOS_ENCOD_DP_QUE_UC(p_sys_queue->sub_chan, p_sys_queue->node[ofst].ofst);
    cmd = DRV_IOR(DsAqmQueueThrdProfileId_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_DP_EN(cmd, p_sys_queue->dp_id), &aqm_que_thrd));
    SetDsAqmQueueThrdProfileId(V, aqmThrdProfileId_f, &aqm_que_thrd, p_sys_queue->node[ofst].drop_wred_profile_id);
    cmd = DRV_IOW(DsAqmQueueThrdProfileId_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_DP_EN(cmd, p_sys_queue->dp_id), &aqm_que_thrd));

    return CTC_E_NONE;
}

int32
sys_at_queue_drop_read_asic(uint8 lchip, uint8 wred_mode, void* p_queue_node, void* p_sys_profile, uint8* hw_valid)
{
    sys_queue_node_t* p_que_node = (sys_queue_node_t*)p_queue_node;
    DsAqmQueueThrdProfileId_m queue_thrd_profile_id;
    uint32 cmd = 0;
    uint32 index = 0;
    uint8 ofst = 0;

    if (!wred_mode)
    {
        return CTC_E_NONE;
    }

    for (ofst = 0; ofst < SYS_QUEUE_SUB_NODE_NUM; ofst++)
    {
        if (SYS_QUE_OFST_UC != p_que_node->node[ofst].type)
        {
            continue;
        }

        index = SYS_AT_QOS_ENCOD_DP_QUE_UC(p_que_node->sub_chan, p_que_node->node[ofst].ofst);
        cmd = DRV_IOR(DsAqmQueueThrdProfileId_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(SYS_PP_BASE(lchip) + p_que_node->pp_id, index, DRV_CMD_DP_EN(cmd, p_que_node->dp_id), &queue_thrd_profile_id));
        ((sys_queue_drop_profile_t*)p_sys_profile)[ofst].p_drop_wred_profile->profile_id = GetDsAqmQueueThrdProfileId(V, aqmThrdProfileId_f, &queue_thrd_profile_id);
        ((sys_queue_drop_profile_t*)p_sys_profile)[ofst].p_drop_wred_profile->dp_id = p_que_node->pp_id * MCHIP_CAP(SYS_CAP_DP_MAX_NUM) + p_que_node->dp_id;
        *hw_valid = 1;
    }

    return CTC_E_NONE;
}

#define ______SYS_AT_QUEUE_DROP_API______

int32
sys_at_queue_set_port_drop_en(uint8 lchip, uint32 chan_id, bool enable, void* p_drop_param)
{
    ctc_qos_resrc_queue_min_t queue_min;
    uint16 sub_chan = 0;

    CTC_ERROR_RETURN(sys_at_get_sub_channel_by_channel(lchip, chan_id, &sub_chan));

    if (enable)
    {
        /* set port guarantee & limit */
        sal_memset(&queue_min, 0, sizeof(ctc_qos_resrc_queue_min_t));
        CTC_ERROR_RETURN(_sys_at_queue_store_buffer_thrd(lchip, 0, chan_id, sub_chan, 0));

        /* enable flush */
        CTC_ERROR_RETURN(_sys_at_queue_set_queue_flush_en(lchip, sub_chan, NULL, 0, enable));
    }
    else
    {
        /* disable flush */
        CTC_ERROR_RETURN(_sys_at_queue_set_queue_flush_en(lchip, sub_chan, NULL, 0, enable));

        /* set port guarantee & limit */
        CTC_ERROR_RETURN(_sys_at_queue_restore_buffer_thrd(lchip, 0, chan_id, sub_chan, 0));
    }

    return CTC_E_NONE;
}

int32
sys_at_set_dma_channel_drop_en(uint8 lchip, bool enable)
{
    uint32 cmd = 0;
    uint16 channel_min = 0;
    uint16 channel_max = 0;
    ds_t ds;

    channel_min = enable ? MCHIP_CAP(SYS_CAP_CHANID_DMA_RX0) : MCHIP_CAP(SYS_CAP_CHANID_RSV);
    channel_max = enable ? MCHIP_CAP(SYS_CAP_CHANID_DMA_RX3) : MCHIP_CAP(SYS_CAP_CHANID_RSV);

    cmd = DRV_IOR(UcQWriteRsvChanCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, ds));
    SetUcQWriteRsvChanCtl(V, g_1_reservedChannelRangeValid_f, ds, 1);
    SetUcQWriteRsvChanCtl(V, g_1_reservedChannelRangeMax_f, ds, channel_max);
    SetUcQWriteRsvChanCtl(V, g_1_reservedChannelRangeMin_f, ds, channel_min);
    cmd = DRV_IOW(UcQWriteRsvChanCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, ds));

    cmd = DRV_IOW(McQWriteRsvChanCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, ds));

    return CTC_E_NONE;
}

int32
sys_at_queue_get_port_depth(uint8 lchip, uint32 chan_id, uint32* p_depth)
{
#if (SDB_MEM_MODEL == SDB_MODE)
    return CTC_E_NONE;
#endif
    uint32 cmd = 0;
    uint16 index = 0;
    DsErmPortCntUc_m ds_cnt_uc;
    DsErmPortCntMc_m ds_cnt_mc;
    uint16 dp_chan = 0;
    uint8 pp_id = 0;
    uint8 dp_id = 0;

    CTC_PTR_VALID_CHECK(p_depth);

    if (SYS_COMMON_USELESS_CHANNEL == chan_id)
    {
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Invalid localphy port \n");
        return CTC_E_INVALID_PORT;
    }

    CTC_ERROR_RETURN(sys_usw_port_api_get_sub_chan_by_chan(lchip, 0, chan_id, &dp_chan, &pp_id, &dp_id));
    SYS_QOS_LCHIP_CONVERT(lchip, pp_id);

    if (dp_chan > SYS_DMPS_LOOP_SUB_CHAN)
    {
        return CTC_E_NONE;
    }

    cmd = DRV_IOR(DsErmPortCntUc_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, dp_chan, DRV_CMD_DP_EN(cmd, dp_id), &ds_cnt_uc));
    index = SYS_AT_QOS_ENCOD_CORE_CHAN(dp_chan, pp_id, dp_id);
    cmd = DRV_IOR(DsErmPortCntMc_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_PP_EN(cmd), &ds_cnt_mc));
    *p_depth = GetDsErmPortCntUc(V, portCnt_f, &ds_cnt_uc) + GetDsErmPortCntMc(V, g_0_portCnt_f, &ds_cnt_mc) + GetDsErmPortCntMc(V, g_1_portCnt_f, &ds_cnt_mc);

    return CTC_E_NONE;
}

int32
sys_at_queue_set_drop_enable(uint8 lchip, uint8 wred_mode, ctc_qos_drop_t* que_drop,
                                      sys_queue_node_t* p_que_node)
{
    uint8 is_dynamic = 0;

    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    CTC_PTR_VALID_CHECK(p_que_node);
    is_dynamic = que_drop->drop.is_dynamic;


    if (!wred_mode)
    {
        return sys_at_resrc_set_que_drop(lchip, is_dynamic, 1, que_drop, p_que_node);
    }

    /*add drop prof and write to asic*/
    CTC_ERROR_RETURN(_sys_at_queue_drop_add_wred_profile(lchip, que_drop, p_que_node));

    return CTC_E_NONE;
}
int32
sys_at_queue_set_drop_disable(uint8 lchip, uint8 wred_mode, ctc_qos_drop_t* que_drop, sys_queue_node_t* p_que_node)
{
    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    CTC_PTR_VALID_CHECK(p_que_node);

    if (!wred_mode)
    {
        return sys_at_resrc_set_que_drop(lchip, 0, 0, que_drop, p_que_node);
    }

    CTC_ERROR_RETURN(_sys_at_queue_drop_remove_wred_profile(lchip, que_drop, p_que_node));

    return CTC_E_NONE;
}

int32
sys_at_queue_wred_set_ecn_mode(uint8 lchip, sys_queue_node_t* p_queue_node, uint8 non_ecn)
{
    uint32 cmd = 0;
    DsAqmActionProfile_m aqm_action_prof;
    uint32 value = 0;

    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    CTC_PTR_VALID_CHECK(p_queue_node);
    if (SYS_QUEUE_TYPE_EXCP == p_queue_node->type || SYS_QUEUE_TYPE_EXCP_UC == p_queue_node->type)
    {
        return CTC_E_NONE;
    }

    SYS_QOS_LCHIP_CONVERT(lchip, p_queue_node->pp_id);

    cmd = DRV_IOR(DsAqmActionProfile_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_queue_node->sub_chan, DRV_CMD_DP_EN(cmd, p_queue_node->dp_id), &aqm_action_prof));
    value = GetDsAqmActionProfile(V, aqmQueActionReset_f, &aqm_action_prof);
    non_ecn ? CTC_BIT_SET(value, p_queue_node->offset) : CTC_BIT_UNSET(value, p_queue_node->offset);
    SetDsAqmActionProfile(V, aqmQueActionReset_f, &aqm_action_prof, value);
    cmd = DRV_IOW(DsAqmActionProfile_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_queue_node->sub_chan, DRV_CMD_DP_EN(cmd, p_queue_node->dp_id), &aqm_action_prof));

    return CTC_E_NONE;
}
int32
sys_at_queue_wred_get_ecn_mode(uint8 lchip, sys_queue_node_t* p_queue_node, uint8* non_ecn)
{
    uint32 cmd = 0;
    DsAqmActionProfile_m aqm_action_prof;
    uint32 value = 0;

    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    CTC_PTR_VALID_CHECK(p_queue_node);
    if (SYS_QUEUE_TYPE_EXCP == p_queue_node->type || SYS_QUEUE_TYPE_EXCP_UC == p_queue_node->type)
    {
        return CTC_E_NONE;
    }

    SYS_QOS_LCHIP_CONVERT(lchip, p_queue_node->pp_id);

    cmd = DRV_IOR(DsAqmActionProfile_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_queue_node->sub_chan, DRV_CMD_DP_EN(cmd, p_queue_node->dp_id), &aqm_action_prof));
    value = GetDsAqmActionProfile(V, aqmQueActionReset_f, &aqm_action_prof);
    *non_ecn = CTC_IS_BIT_SET(value, p_queue_node->offset);

    return CTC_E_NONE;
}


int32
_sys_at_queue_set_queue_drop(uint8 lchip, ctc_qos_drop_t* p_drop)
{
    uint32 max_drop_thrd =  MCHIP_CAP(SYS_CAP_QOS_DROP_TOTAL_UC_POOL_SIZE);
    uint16 queue_id = 0;
    uint8  wred_mode = 0;
    uint8  q_ofst_type = 0;
    ctc_qos_queue_drop_t *p_queue_drop = NULL;
    sys_queue_node_t* p_que_node = NULL;
    uint8 i = 0;

    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    p_queue_drop = &p_drop->drop;

    /*get queue_id*/
    CTC_ERROR_RETURN(sys_at_queue_get_queue_id(lchip,
                                                       &p_drop->queue,
                                                       &queue_id));
    p_que_node = ctc_vector_get(p_usw_queue_master[lchip]->queue_vec, queue_id);
    if (NULL == p_que_node)
    {
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Entry not exist \n");
        return CTC_E_NOT_EXIST;
    }

    CTC_MAX_VALUE_CHECK(p_drop->queue.class_prio, SYS_QUEUE_SUB_NODE_NUM-1);

    /* if normal / eunit queue node is NONE, do nothing */
    q_ofst_type = p_que_node->node[SYS_AT_COS_SUB_NODE_OFST(p_que_node, p_drop->queue.class_prio)].type;
    if ((SYS_QUEUE_TYPE_NORMAL == p_que_node->type || SYS_QUEUE_TYPE_EUNIT == p_que_node->type)
      && SYS_QUE_OFST_NONE == q_ofst_type)
    {
        return CTC_E_INVALID_CONFIG;
    }
    /* excp mc / normal mc need get max_drop_thrd */
    else if (SYS_QUEUE_TYPE_EXCP == p_que_node->type || SYS_QUE_OFST_MC == q_ofst_type)
    {
        max_drop_thrd = MCHIP_CAP(SYS_CAP_QOS_DROP_TOTAL_NON_UC_POOL_SIZE);
    }
    for (i = 0; i < CTC_DROP_PREC_NUM; i++)
    {
        CTC_MAX_VALUE_CHECK(p_queue_drop->max_th[i],    max_drop_thrd );
        CTC_MAX_VALUE_CHECK(p_queue_drop->min_th[i],    p_queue_drop->max_th[i] );
        CTC_MAX_VALUE_CHECK(p_queue_drop->drop_prob[i], MCHIP_CAP(SYS_CAP_QOS_QUEUE_MAX_DROP_PROB) );
        CTC_MAX_VALUE_CHECK(p_queue_drop->drop_factor[i],SYS_MAX_DROP_FACTOR);
    }
    CTC_MAX_VALUE_CHECK(p_queue_drop->weight, SYS_WRED_EWMA_MAX_WEIGHT);
    wred_mode = (p_queue_drop->mode == CTC_QUEUE_DROP_WRED || p_queue_drop->mode == CTC_QUEUE_DROP_WRED_NON_ECN);

    CTC_ERROR_RETURN(sys_at_queue_set_drop_enable(lchip, wred_mode, p_drop, p_que_node));
    if (!p_queue_drop->is_coexist)
    {
        CTC_ERROR_RETURN(sys_at_queue_set_drop_disable(lchip, !wred_mode, p_drop, p_que_node));
    }
    if (wred_mode)
    {
        CTC_ERROR_RETURN(sys_at_queue_wred_set_ecn_mode(lchip, p_que_node, (p_queue_drop->mode == CTC_QUEUE_DROP_WRED_NON_ECN)));
    }
    return CTC_E_NONE;
}

int32
_sys_at_queue_get_queue_drop(uint8 lchip, ctc_qos_drop_t* p_drop)
{
    uint16 queue_id = 0;
    uint8  wred_mode = 0;
    uint8  q_ofst_type = 0;
    sys_queue_node_t* p_que_node = NULL;

    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    /*get queue_id*/
    CTC_ERROR_RETURN(sys_at_queue_get_queue_id(lchip,
                                                       &p_drop->queue,
                                                       &queue_id));
    p_que_node = ctc_vector_get(p_usw_queue_master[lchip]->queue_vec, queue_id);
    if (NULL == p_que_node)
    {
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Entry not exist \n");
        return CTC_E_NOT_EXIST;
    }
    CTC_MAX_VALUE_CHECK(p_drop->queue.class_prio, SYS_QUEUE_SUB_NODE_NUM-1);

    /* if normal / eunit queue node is NONE, do nothing */
    q_ofst_type = p_que_node->node[SYS_AT_COS_SUB_NODE_OFST(p_que_node, p_drop->queue.class_prio)].type;
    if ((SYS_QUEUE_TYPE_NORMAL == p_que_node->type || SYS_QUEUE_TYPE_EUNIT == p_que_node->type)
      && SYS_QUE_OFST_NONE == q_ofst_type)
    {
        return CTC_E_INVALID_CONFIG;
    }
    wred_mode = (p_drop->drop.mode == CTC_QUEUE_DROP_WRED || p_drop->drop.mode == CTC_QUEUE_DROP_WRED_NON_ECN);
    if (wred_mode)
    {
        uint8 non_ecn = 0;
        CTC_ERROR_RETURN(sys_at_queue_wred_get_ecn_mode(lchip, p_que_node, &non_ecn));
        if (non_ecn && p_drop->drop.mode != CTC_QUEUE_DROP_WRED_NON_ECN)
        {
            SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "should used wred CTC_QUEUE_DROP_WRED_NON_ECN to get drop thrd \n");
            return CTC_E_INVALID_CONFIG;
        }
        else if (!non_ecn && p_drop->drop.mode == CTC_QUEUE_DROP_WRED_NON_ECN)
        {
            SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "should used wred CTC_QUEUE_DROP_WRED to get drop thrd \n");
            return CTC_E_INVALID_CONFIG;
        }
    }

    CTC_ERROR_RETURN(sys_at_resrc_get_que_drop(lchip, p_que_node, p_drop, wred_mode, NULL, NULL));

    return CTC_E_NONE;
}
int32
_sys_at_queue_set_prio_class_ecn(uint8 lchip, ctc_qos_drop_t* p_drop, sys_port_info_t* port_info)
{
    /*fast ecn, base on 2 priority*/
    uint32 cmd = 0;
    uint32 field_val1 = 0;
    uint32 field_val2 = 0;
    uint32 prio_class_bmp = 0;
    int32  count = 0;
    int32  count2 = 0;
    uint16 i = 0;
    uint8  dp_id = 0;
    uint8  dp_chan = 0;
    uint8  lchip_tmp = 0;
    uint8  enable = 0;
    uint8  level_bmp[2] = {0};
    uint8  step = 0;
    DsErmPortMbCfg_m erm_port_mb;
    DsErmPortTcMbCfg_m erm_porttc_mb;
    ErmMbCtl_m erm_mb_ctl;
    PreBufferRetrieveCtl_m br_ctl;
    DsDestChannel_m dest_chan;

    if (p_drop->drop.ecn_th[0] && p_drop->drop.ecn_th2[0])
    {
        CTC_MAX_VALUE_CHECK(p_drop->drop.ecn_th[0],    MCHIP_CAP(SYS_CAP_QOS_DROP_TOTAL_UC_POOL_SIZE) );
        CTC_MAX_VALUE_CHECK(p_drop->drop.ecn_th2[0],   MCHIP_CAP(SYS_CAP_QOS_DROP_TOTAL_UC_POOL_SIZE) );
        enable = 1;
    }

    /*1. check port mb and port tc mb*/
    step = DsErmPortTcMbCfg_tc_1_mbSel_f - DsErmPortTcMbCfg_tc_0_mbSel_f;
    for (dp_id = 0; dp_id < SYS_PP_NUM(lchip) * MCHIP_CAP(SYS_CAP_DP_MAX_NUM); dp_id++)
    {
        SYS_QOS_LCHIP_CONVERT(lchip_tmp, dp_id / MCHIP_CAP(SYS_CAP_DP_MAX_NUM));
        for (dp_chan = 0; dp_chan < MCHIP_CAP(SYS_CAP_PER_DP_CHANNEL_NUM); dp_chan++)
        {
            cmd = DRV_IOR(DsErmPortMbCfg_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip_tmp, dp_chan, DRV_CMD_DP_EN(cmd, dp_id % MCHIP_CAP(SYS_CAP_DP_MAX_NUM)), &erm_port_mb));
            field_val1 = GetDsErmPortMbCfg(V, mbInformEn_f, &erm_port_mb);
            if (field_val1)
            {
                return CTC_E_PARAM_CONFLICT;
            }

            cmd = DRV_IOR(DsErmPortTcMbCfg_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip_tmp, dp_chan, DRV_CMD_DP_EN(cmd, dp_id % MCHIP_CAP(SYS_CAP_DP_MAX_NUM)), &erm_porttc_mb));
            field_val1 = GetDsErmPortTcMbCfg(V, g_0_mbInformEn_f, &erm_porttc_mb);
            field_val2 = GetDsErmPortTcMbCfg(V, g_1_mbInformEn_f, &erm_porttc_mb);
            if((field_val1 || field_val2))
            {
                return CTC_E_PARAM_CONFLICT;
            }
            for(i = 0; i < SYS_PRIO_CLASS_NUM; i++)
            {
                field_val1 = GetDsErmPortTcMbCfg(V, tc_0_mbSel_f + step * i, &erm_porttc_mb);
                if(field_val1 != 3)
                {
                    CTC_BIT_SET(prio_class_bmp, i);
                }
            }
        }
    }

    CTC_BMP_COUNT(prio_class_bmp, count, 0, 8);
    CTC_MAX_VALUE_CHECK(count, 2);
    if(count == 0 && enable == 0)
    {
        return CTC_E_NONE;
    }
    else if(count == 2 && !CTC_IS_BIT_SET(prio_class_bmp, p_drop->prio_class))
    {
        return CTC_E_PARAM_CONFLICT;
    }

    /*2. alloc level, only support 2 tc*/
    cmd = DRV_IOR(DsErmPortTcMbCfg_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, port_info->sub_chan_id, DRV_CMD_DP_EN(cmd, port_info->dp_id), &erm_porttc_mb));
    for(i = 0; i < SYS_PRIO_CLASS_NUM; i++)
    {
        field_val1 = GetDsErmPortTcMbCfg(V, tc_0_mbSel_f + step * i, &erm_porttc_mb);
        if(field_val1 == 0)
        {
            CTC_BIT_SET(level_bmp[0], i);
        }
        else if(field_val1 == 1)
        {
            CTC_BIT_SET(level_bmp[1], i);
        }
    }
    if (enable)
    {
        if (!level_bmp[0] || CTC_IS_BIT_SET(level_bmp[0], p_drop->prio_class))
        {
            CTC_BIT_SET(level_bmp[0], p_drop->prio_class);
            SetDsErmPortTcMbCfg(V, tc_0_mbSel_f + step * p_drop->prio_class, &erm_porttc_mb, 0);
            SetDsErmPortTcMbCfg(V, g_0_minThrd_f, &erm_porttc_mb, p_drop->drop.ecn_th2[0]);
            SetDsErmPortTcMbCfg(V, g_0_maxThrd_f, &erm_porttc_mb, p_drop->drop.ecn_th[0]);

        }
        else if (!level_bmp[1] || CTC_IS_BIT_SET(level_bmp[1], p_drop->prio_class))
        {
            CTC_BIT_SET(level_bmp[1], p_drop->prio_class);
            SetDsErmPortTcMbCfg(V, tc_0_mbSel_f + step * p_drop->prio_class, &erm_porttc_mb, 1);
            SetDsErmPortTcMbCfg(V, g_1_minThrd_f, &erm_porttc_mb, p_drop->drop.ecn_th2[0]);
            SetDsErmPortTcMbCfg(V, g_1_maxThrd_f, &erm_porttc_mb, p_drop->drop.ecn_th[0]);
        }
        else
        {
            return CTC_E_NO_RESOURCE;
        }
    }
    else /*disable*/
    {
        if (CTC_IS_BIT_SET(level_bmp[0], p_drop->prio_class))
        {
            CTC_BIT_UNSET(level_bmp[0], p_drop->prio_class);
            field_val1 = GetDsErmPortTcMbCfg(V, tc_0_mbSel_f + step * p_drop->prio_class, &erm_porttc_mb);
            SetDsErmPortTcMbCfg(V, tc_0_mbSel_f + step * p_drop->prio_class, &erm_porttc_mb, 3);
        }
        else if (CTC_IS_BIT_SET(level_bmp[1], p_drop->prio_class))
        {
            CTC_BIT_UNSET(level_bmp[1], p_drop->prio_class);
            field_val1 = GetDsErmPortTcMbCfg(V, tc_0_mbSel_f + step * p_drop->prio_class, &erm_porttc_mb);
            SetDsErmPortTcMbCfg(V, tc_0_mbSel_f + step * p_drop->prio_class, &erm_porttc_mb, 3);
        }
        else
        {
            return CTC_E_NONE;
        }
        step = DsErmPortTcMbCfg_g_1_minThrd_f - DsErmPortTcMbCfg_g_0_minThrd_f;
        SetDsErmPortTcMbCfg(V, g_0_minThrd_f + field_val1 * step, &erm_porttc_mb, 0);
        SetDsErmPortTcMbCfg(V, g_0_maxThrd_f + field_val1 * step, &erm_porttc_mb, 0);
    }
    cmd = DRV_IOW(DsErmPortTcMbCfg_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, port_info->sub_chan_id, DRV_CMD_DP_EN(cmd, port_info->dp_id), &erm_porttc_mb));

    field_val1 = level_bmp[0] || level_bmp[1] ? 1 : 0; /*mean enable*/
    cmd = DRV_IOR(DsDestChannel_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, port_info->chan_id, cmd, &dest_chan));
    SetDsDestChannel(V, microburstAsCongestion_f, &dest_chan, field_val1);
    cmd = DRV_IOW(DsDestChannel_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, port_info->chan_id, cmd, &dest_chan));

    /*global config*/
    prio_class_bmp = 0;
    step = DsErmPortTcMbCfg_tc_1_mbSel_f - DsErmPortTcMbCfg_tc_0_mbSel_f;
    for (dp_id = 0; dp_id < SYS_PP_NUM(lchip) * MCHIP_CAP(SYS_CAP_DP_MAX_NUM); dp_id++)
    {
        SYS_QOS_LCHIP_CONVERT(lchip_tmp, dp_id / MCHIP_CAP(SYS_CAP_DP_MAX_NUM));
        for (dp_chan = 0; dp_chan < MCHIP_CAP(SYS_CAP_PER_DP_CHANNEL_NUM); dp_chan++)
        {
            cmd = DRV_IOR(DsErmPortTcMbCfg_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip_tmp, dp_chan, DRV_CMD_DP_EN(cmd, dp_id % MCHIP_CAP(SYS_CAP_DP_MAX_NUM)), &erm_porttc_mb));
            for(i = 0; i < SYS_PRIO_CLASS_NUM; i++)
            {
                field_val1 = GetDsErmPortTcMbCfg(V, tc_0_mbSel_f + step * i, &erm_porttc_mb);
                if(field_val1 != 3)
                {
                    CTC_BIT_SET(prio_class_bmp, i);
                }
            }
        }
    }

    CTC_BMP_COUNT(prio_class_bmp, count2, 0, 8);
    if (count2 == count)
    {
        return CTC_E_NONE;
    }

    field_val1 = 0;
    level_bmp[0] = 0;
    level_bmp[1] = 0;
    for (i = 0; i < SYS_PRIO_CLASS_NUM; i++)
    {
        if (!CTC_IS_BIT_SET(prio_class_bmp, i) || field_val1 >= 2)
        {
            continue;
        }
        level_bmp[field_val1++] = i;
    }
    cmd = DRV_IOR(ErmMbCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &erm_mb_ctl));
    SetErmMbCtl(V, mbTcMode_f, &erm_mb_ctl, count2 ? 1 : 0);
    SetErmMbCtl(V, g_0_selTc_f, &erm_mb_ctl, level_bmp[0]);
    SetErmMbCtl(V, g_1_selTc_f, &erm_mb_ctl, level_bmp[1]);
    cmd = DRV_IOW(ErmMbCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &erm_mb_ctl));

    cmd = DRV_IOR(PreBufferRetrieveCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &br_ctl));
    SetPreBufferRetrieveCtl(V, mbTcMode_f, &br_ctl, count2 ? 1 : 0);
    SetPreBufferRetrieveCtl(V, g_0_selTc_f, &br_ctl, level_bmp[0]);
    SetPreBufferRetrieveCtl(V, g_1_selTc_f, &br_ctl, level_bmp[1]);
    SetPreBufferRetrieveCtl(V, microburstMode_f, &br_ctl, 0);
    cmd = DRV_IOW(PreBufferRetrieveCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &br_ctl));

    return CTC_E_NONE;
}

int32
_sys_at_queue_get_prio_class_ecn(uint8 lchip, ctc_qos_drop_t* p_drop, sys_port_info_t* port_info)
{
    /*fast ecn, base on 2 priority*/
    uint32 cmd = 0;
    uint32 field_val1 = 0;
    uint16 i = 0;
    uint8  step = 0;
    uint8  level_bmp[2] = {0};
    DsErmPortTcMbCfg_m erm_porttc_mb;
    DsDestChannel_m dest_chan;

    /*1. check fast ecn enable*/
    cmd = DRV_IOR(DsDestChannel_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, port_info->chan_id, DRV_CMD_PP_EN(cmd), &dest_chan));
    field_val1 = GetDsDestChannel(V, microburstAsCongestion_f, &dest_chan);
    if(!field_val1)
    {
        return CTC_E_NONE;
    }
    /*2. get thrd, only support 2 tc*/
    step = DsErmPortTcMbCfg_tc_1_mbSel_f - DsErmPortTcMbCfg_tc_0_mbSel_f;
    cmd = DRV_IOR(DsErmPortTcMbCfg_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, port_info->sub_chan_id, DRV_CMD_DP_EN(cmd, port_info->dp_id), &erm_porttc_mb));
    for(i = 0; i < SYS_PRIO_CLASS_NUM; i++)
    {
        field_val1 = GetDsErmPortTcMbCfg(V, tc_0_mbSel_f + step * i, &erm_porttc_mb);
        if(field_val1 == 0)
        {
            CTC_BIT_SET(level_bmp[0], i);
        }
        else if(field_val1 == 1)
        {
            CTC_BIT_SET(level_bmp[1], i);
        }
    }

    if (CTC_IS_BIT_SET(level_bmp[0], p_drop->prio_class))
    {
        p_drop->drop.ecn_th2[0] = GetDsErmPortTcMbCfg(V, g_0_minThrd_f, &erm_porttc_mb);
        p_drop->drop.ecn_th[0] = GetDsErmPortTcMbCfg(V, g_0_maxThrd_f, &erm_porttc_mb);
    }
    else if  (CTC_IS_BIT_SET(level_bmp[1], p_drop->prio_class))
    {
        p_drop->drop.ecn_th2[0] = GetDsErmPortTcMbCfg(V, g_1_minThrd_f, &erm_porttc_mb);
        p_drop->drop.ecn_th[0] = GetDsErmPortTcMbCfg(V, g_1_maxThrd_f, &erm_porttc_mb);
    }

    return CTC_E_NONE;
}

int32
_sys_at_queue_set_prio_class_drop(uint8 lchip, ctc_qos_drop_t* p_drop)
{
    uint32 cmd = 0;
    uint32 index = 0;
    uint32 tbl_idx = 0;
    uint32 max_drop_thrd = p_drop->non_uc ? MCHIP_CAP(SYS_CAP_QOS_DROP_TOTAL_NON_UC_POOL_SIZE) : MCHIP_CAP(SYS_CAP_QOS_DROP_TOTAL_UC_POOL_SIZE);
    uint16 lport = 0;
    uint16 i = 0;
    uint8  drop_factor[11] = {15,14,13,12,11,10,9,0,1,2,3};
    uint8  is_dynamic = 0;
    uint8  step = 0;
    sys_port_info_t port_info;
    ds_t ds;
    
    CTC_MAX_VALUE_CHECK(p_drop->prio_class ,7);

    sal_memset(&port_info, 0, sizeof(port_info));
    SYS_MAP_CTC_GPORT_TO_DRV_LPORT_WITH_CHECK(p_drop->gport, lchip, lport);
    CTC_ERROR_RETURN(sys_usw_port_api_get_com_info(lchip, lport, CTC_MAP_GPORT_TO_MCHAN_IDX(p_drop->gport), &port_info));
    if (!(SYS_DMPS_NETWORK_PORT == port_info.port_type || SYS_DMPS_CPUMAC_NETWORK_PORT == port_info.port_type || SYS_DMPS_CPU_MAC_PORT == port_info.port_type))
    {
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Invalid localphy port \n");
        return CTC_E_INVALID_PORT;
    }

    SYS_QOS_LCHIP_CONVERT(lchip, port_info.pp_id);

    if (p_drop->dir == CTC_INGRESS)
    {
        CTC_MAX_VALUE_CHECK(p_drop->drop.mode, CTC_QUEUE_DROP_WTD);
        for (i = 0; i < CTC_DROP_PREC_NUM; i++)
        {
            CTC_MAX_VALUE_CHECK(p_drop->drop.max_th[i],    max_drop_thrd );
            CTC_MAX_VALUE_CHECK(p_drop->drop.drop_factor[i],SYS_MAX_DROP_FACTOR);
        }
        step = DsIrmPortTcLimitedThrdProfileUc_g_1_portTcLimitedAutoEn_f - DsIrmPortTcLimitedThrdProfileUc_g_0_portTcLimitedAutoEn_f;
        tbl_idx = p_drop->non_uc ? DsIrmPortTcLimitedThrdProfileMc_t : DsIrmPortTcLimitedThrdProfileUc_t;
        /* TODO xpipe check */
        index = port_info.rx_sub_chan_id << 3 | p_drop->prio_class;
        is_dynamic = p_drop->drop.is_dynamic;
        cmd = DRV_IOR(tbl_idx, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_DP_EN(cmd, port_info.dp_id), &ds));
        for (i = 0; i < CTC_DROP_PREC_NUM; i++)
        {
            SetDsIrmPortTcLimitedThrdProfileUc(V, g_0_portTcLimitedThrd_f + step * i, &ds, (!is_dynamic ? p_drop->drop.max_th[i] : SYS_AT_LIMIT_MAX_THRD_UC) / 8 );
            SetDsIrmPortTcLimitedThrdProfileUc(V, g_0_portTcLimitedFactor_f + step * i, &ds, drop_factor[p_drop->drop.drop_factor[i]]);
            SetDsIrmPortTcLimitedThrdProfileUc(V, g_0_portTcLimitedAutoEn_f + step * i, &ds, is_dynamic ? 1 : 0);
        }
        cmd = DRV_IOW(tbl_idx, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_DP_EN(cmd, port_info.dp_id), &ds));
    }
    else if (p_drop->dir == CTC_EGRESS)
    {
        CTC_ERROR_RETURN(_sys_at_queue_set_prio_class_ecn(lchip, p_drop, &port_info));
    }
    else
    {
        return CTC_E_NOT_SUPPORT;
    }
    return CTC_E_NONE;
}

int32
_sys_at_queue_get_prio_class_drop(uint8 lchip, ctc_qos_drop_t* p_drop)
{
    uint32 cmd = 0;
    uint32 index = 0;
    uint32 tbl_idx = 0;
    uint16 lport = 0;
    uint8 drop_factor[16] = {7,8,9,10,0,0,0,0,0,6,5,4,3,2,1,0};
    uint8  step = 0;
    uint8  i = 0;
    sys_port_info_t port_info;
    ds_t ds;

    CTC_MAX_VALUE_CHECK(p_drop->prio_class ,7);

    SYS_MAP_CTC_GPORT_TO_DRV_LPORT_WITH_CHECK(p_drop->gport, lchip, lport);
    sal_memset(&port_info, 0, sizeof(port_info));
    CTC_ERROR_RETURN(sys_usw_port_api_get_com_info(lchip, lport, CTC_MAP_GPORT_TO_MCHAN_IDX(p_drop->gport), &port_info));
    if (!(SYS_DMPS_NETWORK_PORT == port_info.port_type || SYS_DMPS_CPUMAC_NETWORK_PORT == port_info.port_type || SYS_DMPS_CPU_MAC_PORT == port_info.port_type))
    {
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Invalid localphy port \n");
        return CTC_E_INVALID_PORT;
    }
    SYS_QOS_LCHIP_CONVERT(lchip, port_info.pp_id);

    if (p_drop->dir == CTC_INGRESS)
    {
        CTC_MAX_VALUE_CHECK(p_drop->drop.mode, CTC_QUEUE_DROP_WTD);
        step = DsIrmPortTcLimitedThrdProfileUc_g_1_portTcLimitedAutoEn_f - DsIrmPortTcLimitedThrdProfileUc_g_0_portTcLimitedAutoEn_f;
        tbl_idx = p_drop->non_uc ? DsIrmPortTcLimitedThrdProfileMc_t : DsIrmPortTcLimitedThrdProfileUc_t;
        /* TODO xpipe check */
        index = port_info.rx_sub_chan_id << 3 | p_drop->prio_class;
        cmd = DRV_IOR(tbl_idx, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_DP_EN(cmd, port_info.dp_id), &ds));
        p_drop->drop.is_dynamic = GetDsIrmPortTcLimitedThrdProfileUc(V, g_0_portTcLimitedAutoEn_f, &ds);
        for (i = 0; i < CTC_DROP_PREC_NUM; i++)
        {
            if (!p_drop->drop.is_dynamic)
            {
                p_drop->drop.max_th[i] = GetDsIrmPortTcLimitedThrdProfileUc(V, g_0_portTcLimitedThrd_f + step * i, &ds) * 8;
            }
            else
            {
                p_drop->drop.drop_factor[i] = drop_factor[GetDsIrmPortTcLimitedThrdProfileUc(V, g_0_portTcLimitedFactor_f + step * i, &ds)];
            }
        }
    }
    else if (p_drop->dir == CTC_EGRESS)
    {
        CTC_ERROR_RETURN(_sys_at_queue_get_prio_class_ecn(lchip, p_drop, &port_info));
    }
    else
    {
        return CTC_E_NOT_SUPPORT;
    }

    return CTC_E_NONE;
}

int32
_sys_at_queue_set_portsc_drop(uint8 lchip, ctc_qos_drop_t* p_drop)
{
    uint32 cmd = 0;
    uint32 index = 0;
    uint32 tbl_idx = 0;
    uint32 max_drop_thrd = p_drop->non_uc ? MCHIP_CAP(SYS_CAP_QOS_DROP_TOTAL_NON_UC_POOL_SIZE) : MCHIP_CAP(SYS_CAP_QOS_DROP_TOTAL_UC_POOL_SIZE);
    uint16 lport = 0;
    uint8  drop_factor[11] = {15,14,13,12,11,10,9,0,1,2,3};
    uint8  is_dynamic = 0;
    uint8  i = 0;
    uint8  step = 0;
    sys_port_info_t port_info;
    ds_t ds;

    CTC_MAX_VALUE_CHECK(p_drop->drop.mode, CTC_QUEUE_DROP_WTD);
    CTC_MAX_VALUE_CHECK(p_drop->pool ,CTC_QOS_IGS_RESRC_SC3_POOL);

    for (i = 0; i < CTC_DROP_PREC_NUM; i++)
    {
        CTC_MAX_VALUE_CHECK(p_drop->drop.max_th[i],    max_drop_thrd );
        CTC_MAX_VALUE_CHECK(p_drop->drop.drop_factor[i],SYS_MAX_DROP_FACTOR);
    }

    SYS_MAP_CTC_GPORT_TO_DRV_LPORT_WITH_CHECK(p_drop->gport, lchip, lport);
    sal_memset(&port_info, 0, sizeof(port_info));
    CTC_ERROR_RETURN(sys_usw_port_api_get_com_info(lchip, lport, CTC_MAP_GPORT_TO_MCHAN_IDX(p_drop->gport), &port_info));
    if (!(SYS_DMPS_NETWORK_PORT == port_info.port_type || SYS_DMPS_CPUMAC_NETWORK_PORT == port_info.port_type || SYS_DMPS_CPU_MAC_PORT == port_info.port_type))
    {
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Invalid localphy port \n");
        return CTC_E_INVALID_PORT;
    }

    SYS_QOS_LCHIP_CONVERT(lchip, port_info.pp_id);
    if (p_drop->dir == CTC_INGRESS)
    {
        step = DsIrmPortScLimitedThrdProfileUc_g_1_portScLimitedAutoEn_f - DsIrmPortScLimitedThrdProfileUc_g_0_portScLimitedAutoEn_f;
        tbl_idx = p_drop->non_uc ? DsIrmPortScLimitedThrdProfileMc_t : DsIrmPortScLimitedThrdProfileUc_t;
        /* TODO xpipe check */
        index = port_info.rx_sub_chan_id << 2 | p_drop->pool;
        is_dynamic = p_drop->drop.is_dynamic;
        cmd = DRV_IOR(tbl_idx, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_DP_EN(cmd, port_info.dp_id), &ds));
        for (i = 0; i < CTC_DROP_PREC_NUM; i++)
        {
            SetDsIrmPortScLimitedThrdProfileUc(V, g_0_portScLimitedThrd_f + step * i, &ds, (!is_dynamic ? p_drop->drop.max_th[i] : SYS_AT_LIMIT_MAX_THRD_UC) / 8);
            SetDsIrmPortScLimitedThrdProfileUc(V, g_0_portScLimitedFactor_f + step * i, &ds, drop_factor[p_drop->drop.drop_factor[i]]);
            SetDsIrmPortScLimitedThrdProfileUc(V, g_0_portScLimitedAutoEn_f + step * i, &ds, is_dynamic ? 1 : 0);
        }
        cmd = DRV_IOW(tbl_idx, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_DP_EN(cmd, port_info.dp_id), &ds));
    }
    else if (p_drop->dir == CTC_EGRESS)
    {
        index = port_info.sub_chan_id << 2 | p_drop->pool;
        is_dynamic = p_drop->drop.is_dynamic;
        if(!p_drop->non_uc)
        {
            step = DsErmPortScThrdProfileUc_g_1_portScLimitedAutoEn_f - DsErmPortScThrdProfileUc_g_0_portScLimitedAutoEn_f;
            cmd = DRV_IOR(DsErmPortScThrdProfileUc_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_DP_EN(cmd, port_info.dp_id), &ds));
            for (i = 0; i < CTC_DROP_PREC_NUM; i++)
            {
                SetDsErmPortScThrdProfileUc(V, g_0_portScLimitedThrd_f + step * i, &ds, !is_dynamic ? p_drop->drop.max_th[i] / 8 : SYS_AT_LIMIT_MAX_THRD_UC);
                SetDsErmPortScThrdProfileUc(V, g_0_portScLimitedFactor_f + step * i, &ds, drop_factor[p_drop->drop.drop_factor[i]]);
                SetDsErmPortScThrdProfileUc(V, g_0_portScLimitedAutoEn_f + step * i, &ds, is_dynamic ? 1 : 0);
            }
            cmd = DRV_IOW(DsErmPortScThrdProfileUc_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_DP_EN(cmd, port_info.dp_id), &ds));
         }
        else
        {
            step = DsErmPortScLimitedThrdProfileMc_g_1_portScLimitedAutoEn_f - DsErmPortScLimitedThrdProfileMc_g_0_portScLimitedAutoEn_f;
            cmd = DRV_IOR(DsErmPortScLimitedThrdProfileMc_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_PP_EN(cmd), &ds));
            for (i = 0; i < CTC_DROP_PREC_NUM; i++)
            {
                SetDsErmPortScLimitedThrdProfileMc(V, g_0_portScLimitedThrd_f + step * i, &ds, !is_dynamic ? p_drop->drop.max_th[i] / 8 : SYS_AT_LIMIT_MAX_THRD_MC);
                SetDsErmPortScLimitedThrdProfileMc(V, g_0_portScLimitedFactor_f + step * i, &ds, drop_factor[p_drop->drop.drop_factor[i]]);
                SetDsErmPortScLimitedThrdProfileMc(V, g_0_portScLimitedAutoEn_f + step * i, &ds, is_dynamic ? 1 : 0);
            }
            cmd = DRV_IOW(DsErmPortScLimitedThrdProfileMc_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_PP_EN(cmd), &ds));
        }
    }
    else
    {
        return CTC_E_NOT_SUPPORT;
    }

    return CTC_E_NONE;
}

int32
_sys_at_queue_get_portsc_drop(uint8 lchip, ctc_qos_drop_t* p_drop)
{
    uint32 cmd = 0;
    uint32 index = 0;
    uint32 tbl_idx = 0;
    uint16 lport = 0;
    uint8 drop_factor[16] = {7,8,9,10,0,0,0,0,0,6,5,4,3,2,1,0};
    uint8  i = 0;
    uint8  step = 0;
    sys_port_info_t port_info;
    ds_t ds;

    CTC_MAX_VALUE_CHECK(p_drop->drop.mode, CTC_QUEUE_DROP_WTD);
    CTC_MAX_VALUE_CHECK(p_drop->pool ,CTC_QOS_IGS_RESRC_SC3_POOL);

    SYS_MAP_CTC_GPORT_TO_DRV_LPORT_WITH_CHECK(p_drop->gport, lchip, lport);
    sal_memset(&port_info, 0, sizeof(port_info));
    CTC_ERROR_RETURN(sys_usw_port_api_get_com_info(lchip, lport, CTC_MAP_GPORT_TO_MCHAN_IDX(p_drop->gport), &port_info));
    if (!(SYS_DMPS_NETWORK_PORT == port_info.port_type || SYS_DMPS_CPUMAC_NETWORK_PORT == port_info.port_type || SYS_DMPS_CPU_MAC_PORT == port_info.port_type))
    {
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Invalid localphy port \n");
        return CTC_E_INVALID_PORT;
    }

    SYS_QOS_LCHIP_CONVERT(lchip, port_info.pp_id);
    if (p_drop->dir == CTC_INGRESS)
    {
        step = DsIrmPortScLimitedThrdProfileUc_g_1_portScLimitedAutoEn_f - DsIrmPortScLimitedThrdProfileUc_g_0_portScLimitedAutoEn_f;
        tbl_idx = p_drop->non_uc ? DsIrmPortScLimitedThrdProfileMc_t : DsIrmPortScLimitedThrdProfileUc_t;
        /* TODO xpipe check */
        index = port_info.rx_sub_chan_id << 2 | p_drop->pool;
        cmd = DRV_IOR(tbl_idx, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_DP_EN(cmd, port_info.dp_id), &ds));
        p_drop->drop.is_dynamic = GetDsIrmPortScLimitedThrdProfileUc(V, g_0_portScLimitedAutoEn_f, &ds);
        for (i = 0; i < CTC_DROP_PREC_NUM; i++)
        {
            if (!p_drop->drop.is_dynamic)
            {
                p_drop->drop.max_th[i] = GetDsIrmPortScLimitedThrdProfileUc(V, g_0_portScLimitedThrd_f + step * i, &ds) * 8;
            }
            else
            {
                p_drop->drop.drop_factor[i] = drop_factor[GetDsIrmPortScLimitedThrdProfileUc(V, g_0_portScLimitedFactor_f + step * i, &ds)];
            }
        }
    }
    else if (p_drop->dir == CTC_EGRESS)
    {
        index = port_info.sub_chan_id << 2 | p_drop->pool;
        if(!p_drop->non_uc)
        {
            step = DsErmPortScThrdProfileUc_g_1_portScLimitedAutoEn_f - DsErmPortScThrdProfileUc_g_0_portScLimitedAutoEn_f;
            cmd = DRV_IOR(DsErmPortScThrdProfileUc_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_DP_EN(cmd, port_info.dp_id), &ds));
            p_drop->drop.is_dynamic = GetDsErmPortScThrdProfileUc(V, g_0_portScLimitedAutoEn_f, &ds);
            for (i = 0; i < CTC_DROP_PREC_NUM; i++)
            {
                if (!p_drop->drop.is_dynamic)
                {
                    p_drop->drop.max_th[i] = GetDsErmPortScThrdProfileUc(V, g_0_portScLimitedThrd_f + step * i, &ds) * 8;
                }
                else
                {
                    p_drop->drop.drop_factor[i] = drop_factor[GetDsErmPortScThrdProfileUc(V, g_0_portScLimitedFactor_f + step * i, &ds)];
                }
            }
        }
        else
        {
            step = DsErmPortScLimitedThrdProfileMc_g_1_portScLimitedAutoEn_f - DsErmPortScLimitedThrdProfileMc_g_0_portScLimitedAutoEn_f;
            cmd = DRV_IOR(DsErmPortScLimitedThrdProfileMc_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_PP_EN(cmd), &ds));
            p_drop->drop.is_dynamic = GetDsErmPortScLimitedThrdProfileMc(V, g_0_portScLimitedAutoEn_f, &ds);
            for (i = 0; i < CTC_DROP_PREC_NUM; i++)
            {
                if (!p_drop->drop.is_dynamic)
                {
                    p_drop->drop.max_th[i] = GetDsErmPortScLimitedThrdProfileMc(V, g_0_portScLimitedThrd_f + step * i, &ds) * 8;
                }
                else
                {
                    p_drop->drop.drop_factor[i] = drop_factor[GetDsErmPortScLimitedThrdProfileMc(V, g_0_portScLimitedFactor_f + step * i, &ds)];
                }
            }
        }
    }
    else
    {
        return CTC_E_NOT_SUPPORT;
    }

    return CTC_E_NONE;
}

int32
_sys_at_queue_set_port_drop(uint8 lchip, ctc_qos_drop_t* p_drop)
{
    uint32 cmd = 0;
    uint32 index = 0;
    uint32 tbl_idx = 0;
    uint32 max_drop_thrd = p_drop->non_uc ? MCHIP_CAP(SYS_CAP_QOS_DROP_TOTAL_NON_UC_POOL_SIZE) : MCHIP_CAP(SYS_CAP_QOS_DROP_TOTAL_UC_POOL_SIZE);
    uint16 lport = 0;
    uint8  drop_factor[11] = {15,14,13,12,11,10,9,0,1,2,3};
    uint8  i = 0;
    uint8  step = 0;
    sys_port_info_t port_info;
    ds_t ds;

    for (i = 0; i < CTC_DROP_PREC_NUM; i++)
    {
        CTC_MAX_VALUE_CHECK(p_drop->drop.max_th[i],    max_drop_thrd );
        CTC_MAX_VALUE_CHECK(p_drop->drop.drop_factor[i],SYS_MAX_DROP_FACTOR);
    }
    CTC_MAX_VALUE_CHECK(p_drop->drop.weight, SYS_WRED_EWMA_MAX_WEIGHT);
    SYS_MAP_CTC_GPORT_TO_DRV_LPORT_WITH_CHECK(p_drop->gport, lchip, lport);
    sal_memset(&port_info, 0, sizeof(port_info));
    CTC_ERROR_RETURN(sys_usw_port_api_get_com_info(lchip, lport, CTC_MAP_GPORT_TO_MCHAN_IDX(p_drop->gport), &port_info));
    if (!(SYS_DMPS_NETWORK_PORT == port_info.port_type || SYS_DMPS_CPUMAC_NETWORK_PORT == port_info.port_type || SYS_DMPS_CPU_MAC_PORT == port_info.port_type))
    {
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Invalid localphy port \n");
        return CTC_E_INVALID_PORT;
    }

    SYS_QOS_LCHIP_CONVERT(lchip, port_info.pp_id);
    if (p_drop->dir == CTC_INGRESS)
    {
        CTC_MAX_VALUE_CHECK(p_drop->drop.mode, CTC_QUEUE_DROP_WTD);
        step = DsIrmPortLimitedThrdProfileUc_g_1_portLimitedAutoEn_f - DsIrmPortLimitedThrdProfileUc_g_0_portLimitedAutoEn_f;
        tbl_idx = p_drop->non_uc ? DsIrmPortLimitedThrdProfileMc_t : DsIrmPortLimitedThrdProfileUc_t;
        cmd = DRV_IOR(tbl_idx, DRV_ENTRY_FLAG);
        /* TODO xpipe check */
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, port_info.rx_sub_chan_id, DRV_CMD_DP_EN(cmd, port_info.dp_id), &ds));
        for (i = 0; i < CTC_DROP_PREC_NUM; i++)
        {
            SetDsIrmPortLimitedThrdProfileUc(V, g_0_portLimitedThrd_f + step * i, &ds, (!p_drop->drop.is_dynamic ? p_drop->drop.max_th[i] : SYS_AT_LIMIT_MAX_THRD_UC) / 8);
            SetDsIrmPortLimitedThrdProfileUc(V, g_0_portLimitedFactor_f + step * i, &ds, drop_factor[p_drop->drop.drop_factor[i]]);
            SetDsIrmPortLimitedThrdProfileUc(V, g_0_portLimitedAutoEn_f + step * i, &ds, p_drop->drop.is_dynamic ? 1 : 0);
        }
        cmd = DRV_IOW(tbl_idx, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, port_info.rx_sub_chan_id, DRV_CMD_DP_EN(cmd, port_info.dp_id), &ds));
    }
    else if (p_drop->dir == CTC_EGRESS)
    {
        sys_qos_buffer_info_t* p_buffer_info = NULL;
        p_buffer_info = ctc_vector_get(p_usw_queue_master[lchip]->buffer_info_vec, port_info.chan_id);
        if(!p_drop->non_uc)
        {
            CTC_MAX_VALUE_CHECK(p_drop->drop.mode, CTC_QUEUE_DROP_WRED);
            if(p_drop->drop.mode == CTC_QUEUE_DROP_WRED)
            {
                for (i = 0; i < CTC_DROP_PREC_NUM; i++)
                {
                    CTC_MAX_VALUE_CHECK(p_drop->drop.drop_prob[i], MCHIP_CAP(SYS_CAP_QOS_QUEUE_MAX_DROP_PROB) );
                }
            }
            /*wtd*/
            if(p_drop->drop.mode == CTC_QUEUE_DROP_WTD || p_drop->drop.is_coexist == 0)
            {
                uint8 need_disable = p_drop->drop.mode == CTC_QUEUE_DROP_WTD ? 0 : 1;
                step = DsErmPortThrdProfileUc_g_1_portLimitedAutoEn_f - DsErmPortThrdProfileUc_g_0_portLimitedAutoEn_f;
                cmd = DRV_IOR(DsErmPortThrdProfileUc_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, port_info.sub_chan_id, DRV_CMD_DP_EN(cmd, port_info.dp_id), &ds));
                for (i = 0; i < CTC_DROP_PREC_NUM; i++)
                {
                    SetDsErmPortThrdProfileUc(V, g_0_portLimitedThrd_f + step * i, &ds, (!need_disable && !p_drop->drop.is_dynamic) ? p_drop->drop.max_th[i] / 8 : SYS_AT_LIMIT_MAX_THRD_UC);
                    SetDsErmPortThrdProfileUc(V, g_0_portLimitedFactor_f + step * i, &ds, drop_factor[p_drop->drop.drop_factor[i]]);
                    SetDsErmPortThrdProfileUc(V, g_0_portLimitedAutoEn_f + step * i, &ds, (!need_disable && p_drop->drop.is_dynamic) ? 1 : 0);
                }
                cmd = DRV_IOW(DsErmPortThrdProfileUc_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, port_info.sub_chan_id, DRV_CMD_DP_EN(cmd, port_info.dp_id), &ds));
                if (p_buffer_info)
                {
                    SetDsErmPortThrdProfileUc(V, portGuaranteedThrd_f, &ds, GetDsErmPortThrdProfileUc(V, portGuaranteedThrd_f, &p_buffer_info->port_thrd_uc));
                    sal_memcpy(&p_buffer_info->port_thrd_uc, &ds, sizeof(DsErmPortThrdProfileUc_m));
                }
            }
            /*wred*/
            if(p_drop->drop.mode == CTC_QUEUE_DROP_WRED || p_drop->drop.is_coexist == 0)
            {
                uint32 field_value = 0;
                uint32 drop_prob_tmp = 0;
                uint8 need_disable = p_drop->drop.mode == CTC_QUEUE_DROP_WRED ? 0 : 1;
                step = DsAqmPortThrdProfile_g_1_wredAvgMaxLen_f - DsAqmPortThrdProfile_g_0_wredAvgMaxLen_f;
                cmd = DRV_IOR(DsAqmPortThrdProfile_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, port_info.sub_chan_id, DRV_CMD_DP_EN(cmd, port_info.dp_id), &ds));
                for (i = 0; i < CTC_DROP_PREC_NUM; i++)
                {
                    SetDsAqmPortThrdProfile(V, g_0_wredAvgMaxLen_f + step * i, &ds, need_disable ? SYS_AT_LIMIT_MAX_THRD_UC : p_drop->drop.max_th[i] / 8);
                    SetDsAqmPortThrdProfile(V, g_0_wredAvgMinLen_f + step * i, &ds, need_disable ? SYS_AT_LIMIT_MAX_THRD_UC : p_drop->drop.min_th[i] / 8);
                    SetDsAqmPortThrdProfile(V, g_0_wredProbFactor_f + step * i, &ds, need_disable ? 0 : p_drop->drop.drop_prob[i] * 127 / 100);
                }
                cmd = DRV_IOW(DsAqmPortThrdProfile_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, port_info.sub_chan_id, DRV_CMD_DP_EN(cmd, port_info.dp_id), &ds));

                /*prob quantification*/
                step = DsAqmPortThrdQuantProfile_g_1_wredAvgMaxLen_f - DsAqmPortThrdQuantProfile_g_0_wredAvgMaxLen_f;
                cmd = DRV_IOR(DsAqmPortThrdQuantProfile_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, port_info.sub_chan_id, DRV_CMD_DP_EN(cmd, port_info.dp_id), &ds));
                for (i = 0; i < CTC_DROP_PREC_NUM; i++)
                {
                    field_value = (p_drop->drop.max_th[i] - p_drop->drop.min_th[i]) / 8;
                    drop_prob_tmp = p_drop->drop.drop_prob[i] * 127 / 100 / 8;
                    for (index = 0; index < 7; index++)
                    {
                        SetDsAqmPortThrdQuantProfile(V, g_0_wredAvgMaxLen_f + step * (index << 2 | i), &ds, need_disable? 0 : (p_drop->drop.min_th[i] + field_value*(index+1)) / 8);
                        SetDsAqmPortThrdQuantProfile(V, g_0_wredProbFactor_f + step * (index << 2 | i), &ds, need_disable? 0 : drop_prob_tmp*(index+1));
                    }
                }
                cmd = DRV_IOW(DsAqmPortThrdQuantProfile_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, port_info.sub_chan_id, DRV_CMD_DP_EN(cmd, port_info.dp_id), &ds));

                cmd = DRV_IOR(DsAqmPortCfg_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, port_info.sub_chan_id, DRV_CMD_DP_EN(cmd, port_info.dp_id), &ds));
                SetDsAqmPortCfg(V, ewmaWeightFactor_f, &ds, need_disable? 0 : (p_drop->drop.weight ? p_drop->drop.weight : 1));
                cmd = DRV_IOW(DsAqmPortCfg_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, port_info.sub_chan_id, DRV_CMD_DP_EN(cmd, port_info.dp_id), &ds));
            }
        }
        else
        {
            CTC_MAX_VALUE_CHECK(p_drop->drop.mode, CTC_QUEUE_DROP_WTD);
            index = SYS_AT_QOS_ENCOD_CORE_CHAN(port_info.sub_chan_id, port_info.pp_id, port_info.dp_id);
            step = DsErmPortLimitedThrdProfileMc_g_1_portLimitedAutoEn_f - DsErmPortLimitedThrdProfileMc_g_0_portLimitedAutoEn_f;
            cmd = DRV_IOR(DsErmPortLimitedThrdProfileMc_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_PP_EN(cmd), &ds));
            for (i = 0; i < CTC_DROP_PREC_NUM; i++)
            {
                SetDsErmPortLimitedThrdProfileMc(V, g_0_portLimitedThrd_f + step*i, &ds, !p_drop->drop.is_dynamic ? p_drop->drop.max_th[i] / 8 : SYS_AT_LIMIT_MAX_THRD_MC);
                SetDsErmPortLimitedThrdProfileMc(V, g_0_portLimitedFactor_f + step*i, &ds, drop_factor[p_drop->drop.drop_factor[i]]);
                SetDsErmPortLimitedThrdProfileMc(V, g_0_portLimitedAutoEn_f + step*i, &ds, p_drop->drop.is_dynamic ? 1 : 0);
            }
            cmd = DRV_IOW(DsErmPortLimitedThrdProfileMc_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_PP_EN(cmd), &ds));
            if (p_buffer_info)
            {
                sal_memcpy(&p_buffer_info->port_limited_mc, &ds, sizeof(DsErmPortLimitedThrdProfileMc_m));
            }
        }
    }
    else
    {
        return CTC_E_NOT_SUPPORT;
    }

    return CTC_E_NONE;
}

int32
_sys_at_queue_get_port_drop(uint8 lchip, ctc_qos_drop_t* p_drop)
{
    uint32 cmd = 0;
    uint32 field_val = 0;
    uint32 index = 0;
    uint32 tbl_idx = 0;
    uint16 lport = 0;
    uint8  wred = 0;
    uint8  wtd = 0;
    uint8 drop_factor[16] = {7,8,9,10,0,0,0,0,0,6,5,4,3,2,1,0};
    uint8  i = 0;
    uint8  step = 0;
    sys_port_info_t port_info;
    ds_t ds;


    SYS_MAP_CTC_GPORT_TO_DRV_LPORT_WITH_CHECK(p_drop->gport, lchip, lport);
    sal_memset(&port_info, 0, sizeof(port_info));
    CTC_ERROR_RETURN(sys_usw_port_api_get_com_info(lchip, lport, CTC_MAP_GPORT_TO_MCHAN_IDX(p_drop->gport), &port_info));
    if (!(SYS_DMPS_NETWORK_PORT == port_info.port_type || SYS_DMPS_CPUMAC_NETWORK_PORT == port_info.port_type || SYS_DMPS_CPU_MAC_PORT == port_info.port_type))
    {
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Invalid localphy port \n");
        return CTC_E_INVALID_PORT;
    }

    SYS_QOS_LCHIP_CONVERT(lchip, port_info.pp_id);
    if (p_drop->dir == CTC_INGRESS)
    {
        CTC_MAX_VALUE_CHECK(p_drop->drop.mode, CTC_QUEUE_DROP_WTD);
        step = DsIrmPortLimitedThrdProfileUc_g_1_portLimitedAutoEn_f - DsIrmPortLimitedThrdProfileUc_g_0_portLimitedAutoEn_f;
        tbl_idx = p_drop->non_uc ? DsIrmPortLimitedThrdProfileMc_t : DsIrmPortLimitedThrdProfileUc_t;
        cmd = DRV_IOR(tbl_idx, DRV_ENTRY_FLAG);
        /* TODO xpipe check */
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, port_info.rx_sub_chan_id, DRV_CMD_DP_EN(cmd, port_info.dp_id), &ds));
        p_drop->drop.is_dynamic = GetDsIrmPortLimitedThrdProfileUc(V, g_0_portLimitedAutoEn_f, &ds);
        for (i = 0; i < CTC_DROP_PREC_NUM; i++)
        {
            if (!p_drop->drop.is_dynamic)
            {
                p_drop->drop.max_th[i] = GetDsIrmPortLimitedThrdProfileUc(V, g_0_portLimitedThrd_f + step * i, &ds) * 8;
            }
            else
            {
                p_drop->drop.drop_factor[i] = drop_factor[GetDsIrmPortLimitedThrdProfileUc(V, g_0_portLimitedFactor_f + step * i, &ds)];
            }
        }
    }
    else if (p_drop->dir == CTC_EGRESS)
    {
        if(!p_drop->non_uc)
        {
            CTC_MAX_VALUE_CHECK(p_drop->drop.mode, CTC_QUEUE_DROP_WRED);

            step = DsAqmPortThrdProfile_g_1_wredAvgMaxLen_f - DsAqmPortThrdProfile_g_0_wredAvgMaxLen_f;
            cmd = DRV_IOR(DsAqmPortThrdProfile_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, port_info.sub_chan_id, DRV_CMD_DP_EN(cmd, port_info.dp_id), &ds));
            field_val = GetDsAqmPortThrdProfile(V, g_0_wredAvgMinLen_f, &ds);
            wred = field_val != SYS_AT_LIMIT_MAX_THRD_UC ? 1 : 0;
            if(p_drop->drop.mode == CTC_QUEUE_DROP_WRED)
            {
                for (i = 0; i < CTC_DROP_PREC_NUM; i++)
                {
                    p_drop->drop.max_th[i] = GetDsAqmPortThrdProfile(V, g_0_wredAvgMaxLen_f + step * i, &ds) * 8;
                    p_drop->drop.min_th[i] = GetDsAqmPortThrdProfile(V, g_0_wredAvgMinLen_f + step * i, &ds) * 8;
                    field_val = GetDsErmAqmQueueThrdProfile(V, g_0_wredProbFactor_f + step * i, &ds) * 100;
                    p_drop->drop.drop_prob[i] = (field_val % 127) ? (field_val / 127 + 1) : field_val / 127;
                }
            }

            step = DsErmPortThrdProfileUc_g_1_portLimitedAutoEn_f - DsErmPortThrdProfileUc_g_0_portLimitedAutoEn_f;
            cmd = DRV_IOR(DsErmPortThrdProfileUc_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, port_info.sub_chan_id, DRV_CMD_DP_EN(cmd, port_info.dp_id), &ds));
            p_drop->drop.is_dynamic = GetDsErmPortThrdProfileUc(V, g_0_portLimitedAutoEn_f, &ds);
            field_val = GetDsErmPortThrdProfileUc(V, g_0_portLimitedThrd_f, &ds);
            wtd = (p_drop->drop.is_dynamic ||  field_val != SYS_AT_LIMIT_MAX_THRD_UC) ? 1 : 0;
            if(p_drop->drop.mode == CTC_QUEUE_DROP_WTD)
            {
                for (i = 0; i < CTC_DROP_PREC_NUM; i++)
                {
                    if (!p_drop->drop.is_dynamic)
                    {
                        p_drop->drop.max_th[i] = GetDsErmPortThrdProfileUc(V, g_0_portLimitedThrd_f + step * i, &ds) * 8;
                    }
                    else
                    {
                        p_drop->drop.drop_factor[i] = drop_factor[GetDsErmPortThrdProfileUc(V, g_0_portLimitedFactor_f + step * i, &ds)];
                    }
                }
            }
            p_drop->drop.is_coexist = wred && wtd ? 1 : 0;

            cmd = DRV_IOR(DsAqmPortCfg_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, port_info.sub_chan_id, DRV_CMD_DP_EN(cmd, port_info.dp_id), &ds));
            p_drop->drop.weight =wred ? GetDsAqmPortCfg(V, ewmaWeightFactor_f, &ds) : 0;
        }
        else
        {
            CTC_MAX_VALUE_CHECK(p_drop->drop.mode, CTC_QUEUE_DROP_WTD);
            index = SYS_AT_QOS_ENCOD_CORE_CHAN(port_info.sub_chan_id, port_info.pp_id, port_info.dp_id);
            step = DsErmPortLimitedThrdProfileMc_g_1_portLimitedAutoEn_f - DsErmPortLimitedThrdProfileMc_g_0_portLimitedAutoEn_f;
            cmd = DRV_IOR(DsErmPortLimitedThrdProfileMc_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_PP_EN(cmd), &ds));
            p_drop->drop.is_dynamic = GetDsErmPortLimitedThrdProfileMc(V, g_0_portLimitedAutoEn_f, &ds);
            for (i = 0; i < CTC_DROP_PREC_NUM; i++)
            {
                if (!p_drop->drop.is_dynamic)
                {
                    p_drop->drop.max_th[i] = GetDsErmPortLimitedThrdProfileMc(V, g_0_portLimitedThrd_f + step * i, &ds) * 8;
                }
                else
                {
                    p_drop->drop.drop_factor[i] = drop_factor[GetDsErmPortLimitedThrdProfileMc(V, g_0_portLimitedFactor_f + step * i, &ds)];
                }
            }
        }
    }
    else
    {
        return CTC_E_NOT_SUPPORT;
    }

    return CTC_E_NONE;
}

/*set sc ecn*/
int32
_sys_at_queue_set_sc_drop(uint8 lchip, ctc_qos_drop_t* p_drop)
{
    uint32 cmd = 0;
    uint8  step = 0;
    ds_t ds;
    CTC_MAX_VALUE_CHECK(p_drop->pool, CTC_QOS_EGS_RESRC_SC3_POOL);
    CTC_MAX_VALUE_CHECK(p_drop->drop.ecn_th[0],    MCHIP_CAP(SYS_CAP_QOS_DROP_TOTAL_UC_POOL_SIZE) );
    CTC_MAX_VALUE_CHECK(p_drop->drop.ecn_th2[0],   MCHIP_CAP(SYS_CAP_QOS_DROP_TOTAL_UC_POOL_SIZE) );
    if (p_drop->dir == CTC_EGRESS)
    {
        return CTC_E_INVALID_PARAM;
    }
    /*ON*/
    step = DsAqmScThrd0_g_1_scThrd_f - DsAqmScThrd0_g_0_scThrd_f;
    cmd = DRV_IOR(DsAqmScThrd0_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
    SetDsAqmScThrd0(V, g_0_scEn_f + step * p_drop->pool, &ds, p_drop->drop.ecn_th2[0] ? 1 : 0);
    SetDsAqmScThrd0(V, g_0_scThrd_f + step * p_drop->pool, &ds, p_drop->drop.ecn_th2[0]);
    cmd = DRV_IOW(DsAqmScThrd0_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));

    /*OFF*/
    step = DsAqmScThrd1_g_1_scThrd_f - DsAqmScThrd1_g_0_scThrd_f;
    cmd = DRV_IOR(DsAqmScThrd1_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
    SetDsAqmScThrd1(V, g_0_scEn_f + step * p_drop->pool, &ds, p_drop->drop.ecn_th[0] ? 1 : 0);
    SetDsAqmScThrd1(V, g_0_scThrd_f + step * p_drop->pool, &ds, p_drop->drop.ecn_th[0]);
    cmd = DRV_IOW(DsAqmScThrd1_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
    return CTC_E_NONE;
}


/*get sc ecn*/
int32
_sys_at_queue_get_sc_drop(uint8 lchip, ctc_qos_drop_t* p_drop)
{
    uint32 cmd = 0;
    uint8  step = 0;
    ds_t ds;
    CTC_MAX_VALUE_CHECK(p_drop->pool, CTC_QOS_EGS_RESRC_SC3_POOL)
    if (p_drop->dir == CTC_EGRESS)
    {
        return CTC_E_INVALID_PARAM;
    }
    /*ON*/
    step = DsAqmScThrd0_g_1_scThrd_f - DsAqmScThrd0_g_0_scThrd_f;
    cmd = DRV_IOR(DsAqmScThrd0_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
    p_drop->drop.ecn_th2[0] = GetDsAqmScThrd0(V, g_0_scThrd_f + step * p_drop->pool, &ds);

    /*OFF*/
    step = DsAqmScThrd1_g_1_scThrd_f - DsAqmScThrd1_g_0_scThrd_f;
    cmd = DRV_IOR(DsAqmScThrd1_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
    p_drop->drop.ecn_th[0] = GetDsAqmScThrd1(V, g_0_scThrd_f + step * p_drop->pool, &ds);

    return CTC_E_NONE;
}

int32
sys_at_queue_set_drop(uint8 lchip, ctc_qos_drop_t* p_drop)
{
    CTC_PTR_VALID_CHECK(p_drop);
    switch(p_drop->type)
    {
    case CTC_QOS_BUFFER_NONE:
    case CTC_QOS_BUFFER_QUEUE:
        return _sys_at_queue_set_queue_drop(lchip, p_drop);
    case CTC_QOS_BUFFER_PORT_PRIO_CLASS:
        return _sys_at_queue_set_prio_class_drop(lchip, p_drop);
    case CTC_QOS_BUFFER_PORT_SC:
        return _sys_at_queue_set_portsc_drop(lchip, p_drop);
    case CTC_QOS_BUFFER_PORT:
        return _sys_at_queue_set_port_drop(lchip, p_drop);
    case CTC_QOS_BUFFER_SC:
        return _sys_at_queue_set_sc_drop(lchip, p_drop);
    default:
        return  CTC_E_NOT_SUPPORT;
    }
    return CTC_E_NONE;
}

int32
sys_at_queue_get_drop(uint8 lchip, ctc_qos_drop_t* p_drop)
{
    CTC_PTR_VALID_CHECK(p_drop);
    switch(p_drop->type)
    {
    case CTC_QOS_BUFFER_NONE:
    case CTC_QOS_BUFFER_QUEUE:
        return _sys_at_queue_get_queue_drop(lchip, p_drop);
    case CTC_QOS_BUFFER_PORT_PRIO_CLASS:
        return _sys_at_queue_get_prio_class_drop(lchip, p_drop);
    case CTC_QOS_BUFFER_PORT_SC:
        return _sys_at_queue_get_portsc_drop(lchip, p_drop);
    case CTC_QOS_BUFFER_PORT:
        return _sys_at_queue_get_port_drop(lchip, p_drop);
    case CTC_QOS_BUFFER_SC:
        return _sys_at_queue_get_sc_drop(lchip, p_drop);
    default:
        return  CTC_E_NOT_SUPPORT;
    }
    return CTC_E_NONE;
}

int32
sys_at_qos_set_resrc_classify_pool(uint8 lchip, ctc_qos_resrc_classify_pool_t *p_pool)
{
    ds_t ds;
    sys_port_info_t port_info;
    uint32 cmd                      = 0;
    uint32 field_val                = 0;
    uint32 chan_id                  = 0;
    uint32 gport                    = 0;
    uint32 pp_id = 0;
    uint8 pp_base = SYS_PP_BASE(lchip);
    uint8 step = 0;
    uint16 lport = 0;

    gport = (p_pool->dir == CTC_EGRESS && !p_pool->non_uc) ? p_pool->queue.gport : p_pool->gport;
    SYS_MAP_CTC_GPORT_TO_DRV_LPORT_WITH_CHECK(gport, lchip, lport);
    if (!SYS_GPORT_IS_NETWORK_PORT(gport))
    {
        return CTC_E_INVALID_PORT;
    }
    CTC_MAX_VALUE_CHECK(p_pool->pool, CTC_QOS_IGS_RESRC_SC3_POOL);
    CTC_MAX_VALUE_CHECK(p_pool->priority, MCHIP_CAP(SYS_CAP_QOS_CLASS_PRIORITY_MAX));
    sal_memset(&port_info, 0, sizeof(sys_port_info_t));
    CTC_ERROR_RETURN(sys_usw_port_api_get_com_info(lchip, lport, CTC_MAP_GPORT_TO_MCHAN_IDX(gport), &port_info));
    SYS_QOS_LCHIP_CONVERT(lchip, port_info.pp_id);
    if (p_pool->dir == CTC_INGRESS)
    {
        /* TODO xpipe check */
        chan_id = port_info.rx_chan_id;
        CTC_MAX_VALUE_CHECK(chan_id, MCHIP_CAP(SYS_CAP_CHANNEL_NUM) - 1);
        if (p_pool->non_uc)
        {
            for (pp_id = pp_base; pp_id < (SYS_PP_NUM(lchip) + pp_base); pp_id++)
            {
                cmd = DRV_IOR(DsResrcMgmtRxPrioMapMc_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(pp_id, chan_id, DRV_CMD_PP_EN(cmd), &ds));
                step = DsResrcMgmtRxPrioMapMc_g0_1_mappedSc_f - DsResrcMgmtRxPrioMapMc_g0_0_mappedSc_f;
                SetDsResrcMgmtRxPrioMapMc(V, g0_0_mappedSc_f + p_pool->priority * step, &ds, p_pool->pool);
                cmd = DRV_IOW(DsResrcMgmtRxPrioMapMc_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(pp_id, chan_id, DRV_CMD_PP_EN(cmd), &ds));
            }
        }
        else
        {
            for (pp_id = pp_base; pp_id < (SYS_PP_NUM(lchip) + pp_base); pp_id++)
            {
                cmd = DRV_IOR(DsResrcMgmtRxPrioMapUc_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(pp_id, chan_id, DRV_CMD_PP_EN(cmd), &ds));
                step = DsResrcMgmtRxPrioMapUc_g0_1_mappedSc_f - DsResrcMgmtRxPrioMapUc_g0_0_mappedSc_f;
                SetDsResrcMgmtRxPrioMapUc(V, g0_0_mappedSc_f + p_pool->priority * step, &ds, p_pool->pool);
                cmd = DRV_IOW(DsResrcMgmtRxPrioMapUc_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(pp_id, chan_id, DRV_CMD_PP_EN(cmd), &ds));
            }
        }
    }
    else if (p_pool->dir == CTC_EGRESS)
    {
        /* TODO xpipe check */
        if(p_pool->queue.queue_type == CTC_QUEUE_TYPE_EXCP_CPU)
        {
            chan_id = MCHIP_CAP(SYS_CAP_CHANID_DMA_RX0);
        }
        else
        {
            chan_id = port_info.chan_id;
        }
        CTC_MAX_VALUE_CHECK(chan_id, MCHIP_CAP(SYS_CAP_CHANNEL_NUM) - 1);
        if (p_pool->non_uc)
        {
            for (pp_id = pp_base; pp_id < (SYS_PP_NUM(lchip) + pp_base); pp_id++)
            {
                cmd = DRV_IOR(DsResrcMgmtTxPrioMapMc_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(pp_id, chan_id, DRV_CMD_PP_EN(cmd), &ds));
                step = DsResrcMgmtTxPrioMapMc_g0_1_mappedSc_f - DsResrcMgmtTxPrioMapMc_g0_0_mappedSc_f;
                SetDsResrcMgmtTxPrioMapMc(V, g0_0_mappedSc_f + p_pool->priority * step, &ds, p_pool->pool);
                cmd = DRV_IOW(DsResrcMgmtTxPrioMapMc_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(pp_id, chan_id, DRV_CMD_PP_EN(cmd), &ds));
            }
        }
        else
        {
            uint16 queue_id = 0;
            uint16 index = 0;
            uint8  ofst = 0;
            sys_queue_node_t* p_que_node = NULL;

            CTC_MAX_VALUE_CHECK(p_pool->queue.class_prio, SYS_QUEUE_SUB_NODE_NUM-1);

            CTC_ERROR_RETURN(sys_at_queue_get_queue_id(lchip,  &p_pool->queue, &queue_id));
            p_que_node = ctc_vector_get(p_usw_queue_master[lchip]->queue_vec, queue_id);
            if (NULL == p_que_node)
            {
                SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Entry not exist \n");
                return CTC_E_NOT_EXIST;
            }

            ofst = SYS_AT_COS_SUB_NODE_OFST(p_que_node, p_pool->queue.class_prio);
            if (SYS_QUEUE_TYPE_NORMAL == p_que_node->type || SYS_QUEUE_TYPE_EUNIT == p_que_node->type)
            {
                if (SYS_QUE_OFST_UC != p_que_node->node[ofst].type)
                {
                    return CTC_E_INVALID_CONFIG;
                }
                index = SYS_AT_QOS_ENCOD_DP_QUE_UC(p_que_node->sub_chan, p_que_node->node[ofst].ofst);
                cmd = DRV_IOR(DsErmQueueThrdProfileUc_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_DP_EN(cmd, p_que_node->dp_id), &ds));
                SetDsErmQueueThrdProfileUc(V, sc_f, &ds, p_pool->pool);
                cmd = DRV_IOW(DsErmQueueThrdProfileUc_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_DP_EN(cmd, p_que_node->dp_id), &ds));
            }
            else if (SYS_QUEUE_TYPE_EXCP_UC == p_que_node->type)
            {
                cmd = DRV_IOR(DsErmDmaThrdProfileUc_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_que_node->offset, cmd, &ds));
                SetDsErmDmaThrdProfileUc(V, sc_f, &ds, p_pool->pool);
                cmd = DRV_IOW(DsErmDmaThrdProfileUc_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_que_node->offset, cmd, &ds));
            }

            for (pp_id = pp_base; pp_id < (SYS_PP_NUM(lchip) + pp_base); pp_id++)
            {
                cmd = DRV_IOR(DsResrcMgmtTxPrioMapUc_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(pp_id, chan_id, DRV_CMD_PP_EN(cmd), &ds));
                for (index = 0; index <= MCHIP_CAP(SYS_CAP_QOS_CLASS_PRIORITY_MAX); index++)
                {
                    step = DsResrcMgmtTxPrioMapUc_g0_1_mappedTc_f - DsResrcMgmtTxPrioMapUc_g0_0_mappedTc_f;
                    field_val = GetDsResrcMgmtTxPrioMapUc(V, g0_0_mappedTc_f + index * step, &ds);
                    if (SYS_QUE_OFST_UC == p_que_node->node[ofst].type && field_val == p_que_node->node[ofst].ofst)
                    {
                        step = DsResrcMgmtTxPrioMapUc_g0_1_mappedSc_f - DsResrcMgmtTxPrioMapUc_g0_0_mappedSc_f;
                        SetDsResrcMgmtTxPrioMapUc(V, g0_0_mappedSc_f + index * step, &ds, p_pool->pool);
                    }
                }
                cmd = DRV_IOW(DsResrcMgmtTxPrioMapUc_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(pp_id, chan_id, DRV_CMD_PP_EN(cmd), &ds));
            }
        }
    }
    else
    {
        return CTC_E_INVALID_PARAM;
    }

    return CTC_E_NONE;
}

int32
sys_at_qos_get_resrc_classify_pool(uint8 lchip, ctc_qos_resrc_classify_pool_t *p_pool)
{
    uint32 cmd                      = 0;
    uint32 chan_id                  = 0;
    uint32 gport                    = 0;
    uint8 step = 0;
    uint16 lport = 0;
    ds_t ds;
    sys_port_info_t port_info = {0};

    gport = (p_pool->dir == CTC_EGRESS && !p_pool->non_uc) ? p_pool->queue.gport : p_pool->gport;
    SYS_GLOBAL_PORT_CHECK(gport);
    CTC_MAX_VALUE_CHECK(p_pool->pool, CTC_QOS_IGS_RESRC_SC3_POOL);
    CTC_MAX_VALUE_CHECK(p_pool->priority, MCHIP_CAP(SYS_CAP_QOS_CLASS_PRIORITY_MAX));
    SYS_MAP_CTC_GPORT_TO_DRV_LPORT_WITH_CHECK(gport, lchip, lport);
    if (!SYS_GPORT_IS_NETWORK_PORT(gport))
    {
        return CTC_E_INVALID_PORT;
    }
    CTC_ERROR_RETURN(sys_usw_port_api_get_com_info(lchip, lport, CTC_MAP_GPORT_TO_MCHAN_IDX(gport), &port_info));
    SYS_QOS_LCHIP_CONVERT(lchip, port_info.pp_id);
    if (p_pool->dir == CTC_INGRESS)
    {
        /* TODO xpipe check */
        chan_id = port_info.rx_chan_id;
        CTC_MAX_VALUE_CHECK(chan_id, MCHIP_CAP(SYS_CAP_CHANNEL_NUM) - 1);

        if (p_pool->non_uc)
        {
            cmd = DRV_IOR(DsResrcMgmtRxPrioMapMc_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, chan_id, DRV_CMD_PP_EN(cmd), &ds));
            step = DsResrcMgmtRxPrioMapMc_g0_1_mappedSc_f - DsResrcMgmtRxPrioMapMc_g0_0_mappedSc_f;
            p_pool->pool = GetDsResrcMgmtRxPrioMapMc(V, g0_0_mappedSc_f + p_pool->priority * step, &ds);
        }
        else
        {
            cmd = DRV_IOR(DsResrcMgmtRxPrioMapUc_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, chan_id, DRV_CMD_PP_EN(cmd), &ds));
            step = DsResrcMgmtRxPrioMapUc_g0_1_mappedSc_f - DsResrcMgmtRxPrioMapUc_g0_0_mappedSc_f;
            p_pool->pool = GetDsResrcMgmtRxPrioMapUc(V, g0_0_mappedSc_f + p_pool->priority * step, &ds);
        }
    }
    else if (p_pool->dir == CTC_EGRESS)
    {
        /* TODO xpipe check */
        chan_id = port_info.chan_id;
        CTC_MAX_VALUE_CHECK(chan_id, MCHIP_CAP(SYS_CAP_CHANNEL_NUM) - 1);

        if (p_pool->non_uc)
        {
            cmd = DRV_IOR(DsResrcMgmtTxPrioMapMc_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, chan_id, DRV_CMD_PP_EN(cmd), &ds));
            step = DsResrcMgmtTxPrioMapMc_g0_1_mappedSc_f - DsResrcMgmtTxPrioMapMc_g0_0_mappedSc_f;
            p_pool->pool = GetDsResrcMgmtTxPrioMapMc(V, g0_0_mappedSc_f + p_pool->priority * step, &ds);
        }
        else
        {
            uint16 queue_id = 0;
            uint16 index = 0;
            uint8 ofst = 0;
            sys_queue_node_t* p_que_node = NULL;

            CTC_MAX_VALUE_CHECK(p_pool->queue.class_prio, SYS_QUEUE_SUB_NODE_NUM-1);

            CTC_ERROR_RETURN(sys_at_queue_get_queue_id(lchip,  &p_pool->queue, &queue_id));
            p_que_node = ctc_vector_get(p_usw_queue_master[lchip]->queue_vec, queue_id);
            if (NULL == p_que_node)
            {
                SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Entry not exist \n");
                return CTC_E_NOT_EXIST;
            }
            if (SYS_QUEUE_TYPE_NORMAL == p_que_node->type || SYS_QUEUE_TYPE_EUNIT == p_que_node->type)
            {
                ofst = SYS_AT_COS_SUB_NODE_OFST(p_que_node, p_pool->queue.class_prio);
                if (SYS_QUE_OFST_UC != p_que_node->node[ofst].type)
                {
                    return CTC_E_INVALID_CONFIG;
                }
                index = SYS_AT_QOS_ENCOD_DP_QUE_UC(p_que_node->sub_chan, p_que_node->node[ofst].ofst);
                cmd = DRV_IOR(DsErmQueueThrdProfileUc_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_DP_EN(cmd, p_que_node->dp_id), &ds));
                p_pool->pool = GetDsErmQueueThrdProfileUc(V, sc_f, &ds);
            }
            else if (SYS_QUEUE_TYPE_EXCP_UC == p_que_node->type)
            {
                cmd = DRV_IOR(DsErmDmaThrdProfileUc_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_que_node->offset, cmd, &ds));
                p_pool->pool = GetDsErmDmaThrdProfileUc(V, sc_f, &ds);
            }
        }
    }
    else
    {
        return CTC_E_INVALID_PARAM;
    }

    return CTC_E_NONE;
}
int32
sys_at_queue_set_port_sc_min(uint8 lchip, ctc_qos_resrc_port_min_t *port_min, sys_port_info_t *port_info)
{
    uint16 index                   = 0;
    uint32 cmd                     = 0;
    ds_t ds;

    if ((CTC_INGRESS == port_min->dir) || (CTC_BOTH_DIRECTION == port_min->dir))
    {
        /* TODO xpipe check */
        index = port_info->rx_sub_chan_id << 2 | port_min->prio_class;

        if (!port_min->non_uc)
        {
            cmd = DRV_IOR(DsIrmPortScGuaranteedThrdProfileUc_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_DP_EN(cmd, port_info->dp_id), &ds));
            SetDsIrmPortScGuaranteedThrdProfileUc(V, portScGuaranteedThrd_f, &ds, port_min->threshold);
            cmd = DRV_IOW(DsIrmPortScGuaranteedThrdProfileUc_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_DP_EN(cmd, port_info->dp_id), &ds));
        }
        else
        {
            cmd = DRV_IOR(DsIrmPortScGuaranteedThrdProfileMc_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_DP_EN(cmd, port_info->dp_id), &ds));
            SetDsIrmPortScGuaranteedThrdProfileMc(V, portScGuaranteedThrd_f, &ds, port_min->threshold);
            cmd = DRV_IOW(DsIrmPortScGuaranteedThrdProfileMc_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_DP_EN(cmd, port_info->dp_id), &ds));
        }
    }

    if ((CTC_EGRESS == port_min->dir) || (CTC_BOTH_DIRECTION == port_min->dir))
    {
        /* TODO xpipe check */
        sys_qos_buffer_info_t* p_buffer_info = NULL;
        p_buffer_info = ctc_vector_get(p_usw_queue_master[lchip]->buffer_info_vec, port_info->chan_id);
        if (!port_min->non_uc)
        {
            index = port_info->sub_chan_id << 2 | port_min->prio_class;
            cmd = DRV_IOR(DsErmPortScThrdProfileUc_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_DP_EN(cmd, port_info->dp_id), &ds));
            SetDsErmPortScThrdProfileUc(V, portScGuaranteedThrd_f, &ds, port_min->threshold);
            cmd = DRV_IOW(DsErmPortScThrdProfileUc_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_DP_EN(cmd, port_info->dp_id), &ds));
            if (p_buffer_info)
            {
                SetDsErmPortScThrdProfileUc(V, portScGuaranteedThrd_f, &(p_buffer_info->port_sc_thrd_uc[port_min->prio_class]), port_min->threshold);
            }
        }
        else
        {
            index = (SYS_AT_QOS_ENCOD_CORE_CHAN(port_info->sub_chan_id, port_info->pp_id, port_info->dp_id) << 2) | port_min->prio_class;
            cmd = DRV_IOR(DsErmPortScGuaranteedThrdProfileMc_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_PP_EN(cmd), &ds));
            SetDsErmPortScGuaranteedThrdProfileMc(V, g_0_portScGuaranteedThrd_f, &ds, port_min->threshold);
            cmd = DRV_IOW(DsErmPortScGuaranteedThrdProfileMc_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_PP_EN(cmd), &ds));
            if (p_buffer_info)
            {
                sal_memcpy(&(p_buffer_info->port_sc_guaranteed_mc[port_min->prio_class]), &ds, sizeof(DsErmPortScGuaranteedThrdProfileMc_m));
            }
        }
    }

    return CTC_E_NONE;
}

int32
sys_at_queue_get_port_sc_min(uint8 lchip, ctc_qos_resrc_port_min_t *port_min, sys_port_info_t *port_info)
{
    uint16 index                   = 0;
    uint32 cmd                     = 0;
    ds_t ds;

    if ((CTC_INGRESS == port_min->dir) || (CTC_BOTH_DIRECTION == port_min->dir))
    {
        /* TODO xpipe check */
        index = port_info->rx_sub_chan_id << 2 | port_min->prio_class;
        if (!port_min->non_uc)
        {
            cmd = DRV_IOR(DsIrmPortScGuaranteedThrdProfileUc_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_DP_EN(cmd, port_info->dp_id), &ds));
            port_min->threshold = GetDsIrmPortScGuaranteedThrdProfileUc(V, portScGuaranteedThrd_f, &ds);
        }
        else
        {
            cmd = DRV_IOR(DsIrmPortScGuaranteedThrdProfileMc_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_DP_EN(cmd, port_info->dp_id), &ds));
            port_min->threshold = GetDsIrmPortScGuaranteedThrdProfileMc(V, portScGuaranteedThrd_f, &ds);
        }
    }

    if ((CTC_EGRESS == port_min->dir) || (CTC_BOTH_DIRECTION == port_min->dir))
    {
        if (!port_min->non_uc)
        {
            index = port_info->sub_chan_id << 2 | port_min->prio_class;
            cmd = DRV_IOR(DsErmPortScThrdProfileUc_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_DP_EN(cmd, port_info->dp_id), &ds));
            port_min->threshold = GetDsErmPortScThrdProfileUc(V, portScGuaranteedThrd_f, &ds);
        }
        else
        {
            index = (SYS_AT_QOS_ENCOD_CORE_CHAN(port_info->sub_chan_id, port_info->pp_id, port_info->dp_id) << 2) | port_min->prio_class;
            cmd = DRV_IOR(DsErmPortScGuaranteedThrdProfileMc_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_PP_EN(cmd), &ds));
            port_min->threshold = GetDsErmPortScGuaranteedThrdProfileMc(V, g_0_portScGuaranteedThrd_f, &ds);
        }
    }
    return CTC_E_NONE;
}

int32
sys_at_queue_set_port_min(uint8 lchip, ctc_qos_resrc_port_min_t *port_min)
{
    uint32 cmd                     = 0;
    uint16 lport                   = 0;
    uint16 index                   = 0;
    ds_t ds;
    sys_port_info_t port_info = {0};

    SYS_MAP_CTC_GPORT_TO_DRV_LPORT_WITH_CHECK(port_min->gport, lchip, lport);
    if (!SYS_GPORT_IS_NETWORK_PORT(port_min->gport))
    {
        return CTC_E_INVALID_PORT;
    }
    CTC_ERROR_RETURN(sys_usw_port_api_get_com_info(lchip, lport, CTC_MAP_GPORT_TO_MCHAN_IDX(port_min->gport), &port_info));

    SYS_QOS_LCHIP_CONVERT(lchip, port_info.pp_id);

    if(port_min->prio_class_en == 1)
    {
        /* TODO xpipe check */
        CTC_MAX_VALUE_CHECK(port_min->prio_class, 7);
        CTC_MAX_VALUE_CHECK(port_min->dir, CTC_INGRESS);
        index = port_info.rx_sub_chan_id << 3 | port_min->prio_class;

        if (!port_min->non_uc)
        {
            cmd = DRV_IOR(DsIrmPortTcGuaranteedThrdProfileUc_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_DP_EN(cmd, port_info.dp_id), &ds));
            SetDsIrmPortTcGuaranteedThrdProfileUc(V, portTcGuaranteedThrd_f, &ds, port_min->threshold);
            cmd = DRV_IOW(DsIrmPortTcGuaranteedThrdProfileUc_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_DP_EN(cmd, port_info.dp_id), &ds));
        }
        else
        {
            cmd = DRV_IOR(DsIrmPortTcGuaranteedThrdProfileMc_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_DP_EN(cmd, port_info.dp_id), &ds));
            SetDsIrmPortTcGuaranteedThrdProfileMc(V, portTcGuaranteedThrd_f, &ds, port_min->threshold);
            cmd = DRV_IOW(DsIrmPortTcGuaranteedThrdProfileMc_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_DP_EN(cmd, port_info.dp_id), &ds));
        }
        return CTC_E_NONE;
    }
    else if(port_min->prio_class_en == 2)
    {
        CTC_MAX_VALUE_CHECK(port_min->prio_class, CTC_QOS_IGS_RESRC_SC3_POOL);
        CTC_ERROR_RETURN(sys_at_queue_set_port_sc_min(lchip, port_min, &port_info));
        return CTC_E_NONE;
    }

    /* write profile to asic */
    if ((CTC_INGRESS == port_min->dir) || (CTC_BOTH_DIRECTION == port_min->dir))
    {
        /* TODO xpipe check */
        if (!port_min->non_uc)
        {
            cmd = DRV_IOR(DsIrmPortGuaranteedThrdProfileUc_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, port_info.rx_sub_chan_id, DRV_CMD_DP_EN(cmd, port_info.dp_id), &ds));
            SetDsIrmPortGuaranteedThrdProfileUc(V, portGuaranteedThrd_f, &ds, port_min->threshold);
            cmd = DRV_IOW(DsIrmPortGuaranteedThrdProfileUc_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, port_info.rx_sub_chan_id, DRV_CMD_DP_EN(cmd, port_info.dp_id), &ds));
        }
        else
        {
            cmd = DRV_IOR(DsIrmPortGuaranteedThrdProfileMc_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, port_info.rx_sub_chan_id, DRV_CMD_DP_EN(cmd, port_info.dp_id), &ds));
            SetDsIrmPortGuaranteedThrdProfileMc(V, portGuaranteedThrd_f, &ds, port_min->threshold);
            cmd = DRV_IOW(DsIrmPortGuaranteedThrdProfileMc_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, port_info.rx_sub_chan_id, DRV_CMD_DP_EN(cmd, port_info.dp_id), &ds));
        }
    }

    if ((CTC_EGRESS == port_min->dir) || (CTC_BOTH_DIRECTION == port_min->dir))
    {
        /* TODO xpipe check */
        sys_qos_buffer_info_t* p_buffer_info = NULL;
        p_buffer_info = ctc_vector_get(p_usw_queue_master[lchip]->buffer_info_vec, port_info.chan_id);
        if (!port_min->non_uc)
        {
            cmd = DRV_IOR(DsErmPortThrdProfileUc_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, port_info.sub_chan_id, DRV_CMD_DP_EN(cmd, port_info.dp_id), &ds));
            SetDsErmPortThrdProfileUc(V, portGuaranteedThrd_f, &ds, port_min->threshold);
            cmd = DRV_IOW(DsErmPortThrdProfileUc_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, port_info.sub_chan_id, DRV_CMD_DP_EN(cmd, port_info.dp_id), &ds));
            if (p_buffer_info)
            {
                SetDsErmPortThrdProfileUc(V, portGuaranteedThrd_f, &p_buffer_info->port_thrd_uc, port_min->threshold);
            }
        }
        else
        {
            index = SYS_AT_QOS_ENCOD_CORE_CHAN(port_info.sub_chan_id, port_info.pp_id, port_info.dp_id);
            cmd = DRV_IOR(DsErmPortGuaranteedThrdProfileMc_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_PP_EN(cmd), &ds));
            SetDsErmPortGuaranteedThrdProfileMc(V, g_0_portGuaranteedThrd_f, &ds, port_min->threshold);
            cmd = DRV_IOW(DsErmPortGuaranteedThrdProfileMc_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_PP_EN(cmd), &ds));
            if (p_buffer_info)
            {
                sal_memcpy(&p_buffer_info->port_guaranteed_mc, &ds, sizeof(DsErmPortGuaranteedThrdProfileMc_m));
            }
        }
    }

    return CTC_E_NONE;
}
int32
sys_at_queue_get_port_min(uint8 lchip, ctc_qos_resrc_port_min_t *port_min)
{
    uint32 cmd                     = 0;
    uint16 lport                   = 0;
    uint16 index                   = 0;
    ds_t ds;
    sys_port_info_t port_info = {0};

    SYS_MAP_CTC_GPORT_TO_DRV_LPORT_WITH_CHECK(port_min->gport, lchip, lport);
    if (!SYS_GPORT_IS_NETWORK_PORT(port_min->gport))
    {
        return CTC_E_INVALID_PORT;
    }
    CTC_ERROR_RETURN(sys_usw_port_api_get_com_info(lchip, lport, CTC_MAP_GPORT_TO_MCHAN_IDX(port_min->gport), &port_info));

    SYS_QOS_LCHIP_CONVERT(lchip, port_info.pp_id);

    if(port_min->prio_class_en == 1)
    {
        CTC_MAX_VALUE_CHECK(port_min->prio_class, 7);
        CTC_MAX_VALUE_CHECK(port_min->dir, CTC_INGRESS);
        /* TODO xpipe check */
        index = port_info.rx_sub_chan_id << 3 | port_min->prio_class;
        if (!port_min->non_uc)
        {
            cmd = DRV_IOR(DsIrmPortTcGuaranteedThrdProfileUc_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_DP_EN(cmd, port_info.dp_id), &ds));
            port_min->threshold = GetDsIrmPortTcGuaranteedThrdProfileUc(V, portTcGuaranteedThrd_f, &ds);
        }
        else
        {
            cmd = DRV_IOR(DsIrmPortTcGuaranteedThrdProfileMc_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_DP_EN(cmd, port_info.dp_id), &ds));
            port_min->threshold = GetDsIrmPortTcGuaranteedThrdProfileMc(V, portTcGuaranteedThrd_f, &ds);
        }
        return CTC_E_NONE;
    }
    else if(port_min->prio_class_en == 2)
    {
        CTC_MAX_VALUE_CHECK(port_min->prio_class, CTC_QOS_IGS_RESRC_SC3_POOL);
        CTC_ERROR_RETURN(sys_at_queue_get_port_sc_min(lchip, port_min, &port_info));
        return CTC_E_NONE;
    }

    /* read profile to asic */
    if ((CTC_INGRESS == port_min->dir) || (CTC_BOTH_DIRECTION == port_min->dir))
    {
        /* TODO xpipe check */
        if (!port_min->non_uc)
        {
            cmd = DRV_IOR(DsIrmPortGuaranteedThrdProfileUc_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, port_info.rx_sub_chan_id, DRV_CMD_DP_EN(cmd, port_info.dp_id), &ds));
            port_min->threshold = GetDsIrmPortGuaranteedThrdProfileUc(V, portGuaranteedThrd_f, &ds);
        }
        else
        {
            cmd = DRV_IOR(DsIrmPortGuaranteedThrdProfileMc_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, port_info.rx_sub_chan_id, DRV_CMD_DP_EN(cmd, port_info.dp_id), &ds));
            port_min->threshold = GetDsIrmPortGuaranteedThrdProfileMc(V, portGuaranteedThrd_f, &ds);
        }
    }

    if ((CTC_EGRESS == port_min->dir) || (CTC_BOTH_DIRECTION == port_min->dir))
    {
        if (!port_min->non_uc)
        {
            cmd = DRV_IOR(DsErmPortThrdProfileUc_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, port_info.sub_chan_id, DRV_CMD_DP_EN(cmd, port_info.dp_id), &ds));
            port_min->threshold = GetDsErmPortThrdProfileUc(V, portGuaranteedThrd_f, &ds);
        }
        else
        {
            index = SYS_AT_QOS_ENCOD_CORE_CHAN(port_info.sub_chan_id, port_info.pp_id, port_info.dp_id);
            cmd = DRV_IOR(DsErmPortGuaranteedThrdProfileMc_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_PP_EN(cmd), &ds));
            port_min->threshold = GetDsErmPortGuaranteedThrdProfileMc(V, g_0_portGuaranteedThrd_f, &ds);
        }
    }

    return CTC_E_NONE;
}

int32
sys_at_qos_fc_add_profile(uint8 lchip, ctc_qos_resrc_fc_t *p_fc)
{
    uint32 chan_id = 0;
    sys_usw_dmps_port_info_t dmps_port_info = {0};

    SYS_GLOBAL_PORT_CHECK(p_fc->gport);
    CTC_MAX_VALUE_CHECK(p_fc->priority_class, SYS_PRIO_CLASS_NUM - 1);
    CTC_VALUE_RANGE_CHECK(p_fc->xon_thrd, 1, MCHIP_CAP(SYS_CAP_QOS_DROP_TOTAL_UC_POOL_SIZE) );
    CTC_VALUE_RANGE_CHECK(p_fc->xoff_thrd, 1, MCHIP_CAP(SYS_CAP_QOS_DROP_TOTAL_UC_POOL_SIZE) );
    CTC_VALUE_RANGE_CHECK(p_fc->drop_thrd, 1, MCHIP_CAP(SYS_CAP_QOS_DROP_TOTAL_UC_POOL_SIZE) );
    if(!(p_fc->xon_thrd < p_fc->xoff_thrd && p_fc->xoff_thrd < p_fc->drop_thrd))
    {
        return CTC_E_INVALID_PARAM;
    }

    if (p_fc->is_oobfc)
    {
        return CTC_E_NOT_SUPPORT;
    }

    dmps_port_info.gport = p_fc->gport;
    CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_CHAN_ID, &chan_id));
    if (chan_id == SYS_DMPS_INVALID_CHAN_ID)
    {
        return CTC_E_INVALID_PARAM;
    }

    return sys_at_resrc_fc_set_profile(lchip, chan_id, p_fc);
}

int32
sys_at_qos_fc_get_profile(uint8 lchip, ctc_qos_resrc_fc_t *p_fc)
{
    uint32 chan_id = 0;
    sys_usw_dmps_port_info_t dmps_port_info = {0};

    SYS_GLOBAL_PORT_CHECK(p_fc->gport);
    CTC_MAX_VALUE_CHECK(p_fc->priority_class, SYS_PRIO_CLASS_NUM - 1);

    if (p_fc->is_oobfc)
    {
        return CTC_E_NOT_SUPPORT;
    }

    dmps_port_info.gport = p_fc->gport;
    CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_CHAN_ID, &chan_id));
    if (chan_id == SYS_DMPS_INVALID_CHAN_ID)
    {
        return CTC_E_INVALID_PARAM;
    }

    CTC_ERROR_RETURN(sys_at_resrc_fc_get_profile(lchip, chan_id, p_fc));
    return CTC_E_NONE;
}
int32
sys_at_qos_set_fc_default_profile(uint8 lchip, uint32 gport)
{
    uint8 priority_class = 0;
    ctc_qos_resrc_fc_t fc;
    uint32 port_type = 0;
    sys_usw_dmps_port_info_t dmps_port_info = {0};

    sal_memset(&fc, 0, sizeof(ctc_qos_resrc_fc_t));

    dmps_port_info.gport = gport;
    CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_PORT_TYPE, (void *)&port_type));
    if ((SYS_DMPS_NETWORK_PORT != port_type) && (SYS_DMPS_CPUMAC_NETWORK_PORT != port_type))
    {
         return CTC_E_NONE;
    }

    fc.xon_thrd = 240;
    fc.xoff_thrd = 256;
    fc.drop_thrd = MCHIP_CAP(SYS_CAP_QOS_DROP_TOTAL_UC_POOL_SIZE);
    fc.gport = gport;
    fc.is_pfc = 0;
    for (priority_class = 0; priority_class < SYS_PRIO_CLASS_NUM; priority_class++)
    {
        fc.priority_class = priority_class;
        CTC_ERROR_RETURN(sys_at_qos_fc_add_profile(lchip, &fc));
    }

    return CTC_E_NONE;
}

int32
sys_at_queue_set_queue_min(uint8 lchip, ctc_qos_resrc_queue_min_t queue_min)
{
    uint32 cmd                     = 0;
    uint16 queue_id                 = 0;
    uint32 index = 0;
    uint32 chan_id = 0;
    ds_t ds;
    sys_queue_node_t* p_que_node = NULL;
    sys_qos_buffer_info_t* p_buffer_info = NULL;
    uint8 ofst = 0;
    sys_usw_dmps_port_info_t dmps_port_info = {0};

    CTC_MAX_VALUE_CHECK(queue_min.threshold, SYS_AT_MAX_GUARANTEE);
    CTC_MAX_VALUE_CHECK(queue_min.queue.class_prio, SYS_QUEUE_SUB_NODE_NUM-1);

    CTC_ERROR_RETURN(sys_at_queue_get_queue_id(lchip,  &queue_min.queue, &queue_id));
    p_que_node = ctc_vector_get(p_usw_queue_master[lchip]->queue_vec, queue_id);
    if (NULL == p_que_node)
    {
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Entry not exist \n");
        return CTC_E_NOT_EXIST;
    }
    SYS_QOS_LCHIP_CONVERT(lchip, p_que_node->pp_id);
    if (SYS_QUEUE_TYPE_NORMAL == p_que_node->type || SYS_QUEUE_TYPE_EUNIT == p_que_node->type)
    {
        ofst = SYS_AT_COS_SUB_NODE_OFST(p_que_node, queue_min.queue.class_prio);
        if (SYS_QUE_OFST_UC == p_que_node->node[ofst].type)
        {
            index = SYS_AT_QOS_ENCOD_DP_QUE_UC(p_que_node->sub_chan, p_que_node->node[ofst].ofst);
            cmd = DRV_IOR(DsErmQueueThrdProfileUc_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_DP_EN(cmd, p_que_node->dp_id), &ds));
            SetDsErmQueueThrdProfileUc(V, queueGuaranteedThrd_f, &ds, queue_min.threshold);
            cmd = DRV_IOW(DsErmQueueThrdProfileUc_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_DP_EN(cmd, p_que_node->dp_id), &ds));
        }
        else if (SYS_QUE_OFST_MC == p_que_node->node[ofst].type)
        {
            index = SYS_AT_QOS_ENCOD_CORE_QUE_MC(p_que_node->sub_chan, p_que_node->pp_id, p_que_node->dp_id, p_que_node->node[ofst].ofst);
            cmd = DRV_IOR(DsErmQueueGuaranteedThrdProfileMc_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_PP_EN(cmd), &ds));
            SetDsErmQueueGuaranteedThrdProfileMc(V, g_0_queueGuaranteedThrd_f, &ds, queue_min.threshold);
            cmd = DRV_IOW(DsErmQueueGuaranteedThrdProfileMc_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_PP_EN(cmd), &ds));
        }
    }
    else if (SYS_QUEUE_TYPE_EXCP == p_que_node->type)
    {
        cmd = DRV_IOR(DsErmDmaGuaranteedThrdProfileMc_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_que_node->offset, cmd, &ds));
        SetDsErmDmaGuaranteedThrdProfileMc(V, g_0_queueGuaranteedThrd_f, &ds, queue_min.threshold);
        cmd = DRV_IOW(DsErmDmaGuaranteedThrdProfileMc_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_que_node->offset, cmd, &ds));
    }
    else if (SYS_QUEUE_TYPE_EXCP_UC == p_que_node->type)
    {
        cmd = DRV_IOR(DsErmDmaThrdProfileUc_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_que_node->offset, cmd, &ds));
        SetDsErmDmaThrdProfileUc(V, queueGuaranteedThrd_f, &ds, queue_min.threshold);
        cmd = DRV_IOW(DsErmDmaThrdProfileUc_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_que_node->offset, cmd, &ds));
    }

    dmps_port_info.gport = queue_min.queue.gport;
    CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_CHAN_ID, &chan_id));
    p_buffer_info = ctc_vector_get(p_usw_queue_master[lchip]->buffer_info_vec, chan_id);
    if ((SYS_QUEUE_TYPE_NORMAL != p_que_node->type && SYS_QUEUE_TYPE_EUNIT != p_que_node->type) || !p_buffer_info)
    {
        return CTC_E_NONE;
    }
    if (SYS_QUE_OFST_UC == p_que_node->node[ofst].type)
    {
        CTC_MAX_VALUE_CHECK(p_que_node->node[ofst].ofst, SYS_AT_UC_QUEUE_NUM - 1);
        SetDsErmQueueThrdProfileUc(V, queueGuaranteedThrd_f, &(p_buffer_info->q_thrd_uc[p_que_node->node[ofst].ofst]), queue_min.threshold);
    }
    else if (SYS_QUE_OFST_MC == p_que_node->node[ofst].type)
    {
        CTC_MAX_VALUE_CHECK(p_que_node->node[ofst].ofst, SYS_AT_MC_QUEUE_NUM - 1);
        sal_memcpy(&(p_buffer_info->q_guaranteed_mc[p_que_node->node[ofst].ofst]), &ds, sizeof(DsErmQueueGuaranteedThrdProfileMc_m));
    }
    return CTC_E_NONE;
}

int32
sys_at_queue_get_queue_min(uint8 lchip, ctc_qos_resrc_queue_min_t* queue_min)
{
    uint16 queue_id                 = 0;
    sys_queue_node_t *p_que_node = NULL;
    uint32 index = 0;
    uint32 cmd = 0;
    ds_t ds;
    uint8 ofst = 0;

    CTC_MAX_VALUE_CHECK(queue_min->queue.class_prio, SYS_QUEUE_SUB_NODE_NUM-1);

    CTC_ERROR_RETURN(sys_at_queue_get_queue_id(lchip,  &queue_min->queue, &queue_id));
    p_que_node = ctc_vector_get(p_usw_queue_master[lchip]->queue_vec, queue_id);
    if (NULL == p_que_node)
    {
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Entry not exist \n");
        return CTC_E_NOT_EXIST;
    }

    SYS_QOS_LCHIP_CONVERT(lchip, p_que_node->pp_id);
    if (SYS_QUEUE_TYPE_NORMAL == p_que_node->type || SYS_QUEUE_TYPE_EUNIT == p_que_node->type)
    {
        ofst = SYS_AT_COS_SUB_NODE_OFST(p_que_node, queue_min->queue.class_prio);
        if (SYS_QUE_OFST_UC == p_que_node->node[ofst].type)
        {
            index = SYS_AT_QOS_ENCOD_DP_QUE_UC(p_que_node->sub_chan, p_que_node->node[ofst].ofst);
            cmd = DRV_IOR(DsErmQueueThrdProfileUc_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_DP_EN(cmd, p_que_node->dp_id), &ds));
            queue_min->threshold = GetDsErmQueueThrdProfileUc(V, queueGuaranteedThrd_f, &ds);
        }
        else if (SYS_QUE_OFST_MC == p_que_node->node[ofst].type)
        {
            index = SYS_AT_QOS_ENCOD_CORE_QUE_MC(p_que_node->sub_chan, p_que_node->pp_id, p_que_node->dp_id, p_que_node->node[ofst].ofst);
            cmd = DRV_IOR(DsErmQueueGuaranteedThrdProfileMc_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_PP_EN(cmd), &ds));
            queue_min->threshold = GetDsErmQueueGuaranteedThrdProfileMc(V, g_0_queueGuaranteedThrd_f, &ds);
        }
    }
    else if (SYS_QUEUE_TYPE_EXCP == p_que_node->type)
    {
        cmd = DRV_IOR(DsErmDmaGuaranteedThrdProfileMc_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_que_node->offset, cmd, &ds));
        queue_min->threshold = GetDsErmDmaGuaranteedThrdProfileMc(V, g_0_queueGuaranteedThrd_f, &ds);
    }
    else if (SYS_QUEUE_TYPE_EXCP_UC == p_que_node->type)
    {
        cmd = DRV_IOR(DsErmDmaThrdProfileUc_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_que_node->offset, cmd, &ds));
        queue_min->threshold = GetDsErmDmaThrdProfileUc(V, queueGuaranteedThrd_f, &ds);
    }

    return CTC_E_NONE;
}

int32
sys_at_qos_set_fcdl_action(uint8 lchip, uint32 action)
{
    uint16 loop = 0;
    uint32 cmd = 0;
    ErmMiscCtlUc_m erm_misc_ctl;
    ErmMiscCtlUc_m erm_misc_ctl_mc;

    for(loop = 0; loop < SYS_USW_MAX_PORT_NUM_PER_CHIP; loop++)
    {
        if(p_usw_queue_master[lchip]->fcdl_info[loop].count[0]
            ||p_usw_queue_master[lchip]->fcdl_info[loop].count[1])
        {
            break;
        }
    }
    if(loop != SYS_USW_MAX_PORT_NUM_PER_CHIP)
    {
        return CTC_E_NOT_READY;
    }
    CTC_MAX_VALUE_CHECK(action, CTC_QOS_FCDL_ACTION_MAX - 1);
    p_usw_queue_master[lchip]->fcdl_action = action;

    /*set for drop pkt*/
    cmd = DRV_IOR(ErmMiscCtlUc_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &erm_misc_ctl));
    SetErmMiscCtlUc(V, thrdPassMode_f, &erm_misc_ctl, action == CTC_QOS_FCDL_ACTION_DROP ? 0 : 7);
    cmd = DRV_IOW(ErmMiscCtlUc_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &erm_misc_ctl));

    cmd = DRV_IOR(ErmMiscCtlMc_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &erm_misc_ctl_mc));
    SetErmMiscCtlMc(V, thrdPassMode_f, &erm_misc_ctl_mc, action == CTC_QOS_FCDL_ACTION_DROP ? 0 : 7);
    cmd = DRV_IOW(ErmMiscCtlMc_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &erm_misc_ctl_mc));

    SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_MASTER, 1);
    return CTC_E_NONE;
}

int32
sys_at_qos_set_fcdl_interval(uint8 lchip, uint32 time)
{
    uint32 value = 0;
    uint32 cmd = 0;
    RefDivMiscPulse_m cpumac_pause_pulse;
    RefDivMcMacPulse_m mc_mac_pulse;

    CTC_VALUE_RANGE_CHECK(time, 1, SYS_MAX_FCDL_INTERVAL_TIME);

    /* time = cfgRefDivSgmacPauseLockPulse[30:8] * 6.4ns */
    value = (time * 156250) << 8;

    cmd = DRV_IOR(RefDivMcMacPulse_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &mc_mac_pulse));
    SetRefDivMcMacPulse(V, cfgResetDivMcMacPauseLockPulse_f, &mc_mac_pulse, 0);
    SetRefDivMcMacPulse(V, cfgRefDivMcMacPauseLockPulse_f, &mc_mac_pulse, value);
    cmd = DRV_IOW(RefDivMcMacPulse_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &mc_mac_pulse));

    cmd = DRV_IOR(RefDivMiscPulse_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &cpumac_pause_pulse));
    SetRefDivMiscPulse(V, cfgRefDivCpuMacPauseLockPulse_f, &cpumac_pause_pulse, value);
    SetRefDivMiscPulse(V, cfgResetDivCpuMacPauseLockPulse_f, &cpumac_pause_pulse, 0);
    cmd = DRV_IOW(RefDivMiscPulse_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &cpumac_pause_pulse));

    return CTC_E_NONE;
}
int32
sys_at_qos_get_fcdl_interval(uint8 lchip, uint32* time)
{
    uint32 value = 0;
    uint32 cmd = 0;
    RefDivMcMacPulse_m mc_mac_pulse;

    CTC_PTR_VALID_CHECK(time);

    cmd = DRV_IOR(RefDivMcMacPulse_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &mc_mac_pulse));
    value = GetRefDivMcMacPulse(V, cfgRefDivMcMacPauseLockPulse_f, &mc_mac_pulse);
    *time = (value >> 8) / 156250;

    return CTC_E_NONE;
}

int32
sys_at_qos_set_round_trip_mode(uint8 lchip, uint32 mode)
{
    uint32 cmd = 0;
    BufferStoreCtl_m bs_ctl;

    CTC_MAX_VALUE_CHECK(mode, 1);

    cmd = DRV_IOR(BufferStoreCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &bs_ctl));
    SetBufferStoreCtl(V, headroomCheckMode_f, &bs_ctl, mode ? 1 : 0);
    cmd = DRV_IOW(BufferStoreCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &bs_ctl));


    return CTC_E_NONE;
}

int32
sys_at_qos_get_round_trip_mode(uint8 lchip, uint32* mode)
{
    uint32 cmd = 0;
    BufferStoreCtl_m bs_ctl;

    CTC_PTR_VALID_CHECK(mode);

    cmd = DRV_IOR(BufferStoreCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &bs_ctl));
    *mode = GetBufferStoreCtl(V, headroomCheckMode_f, &bs_ctl);

    return CTC_E_NONE;
}

STATIC int32
_sys_at_qos_fcdl_recover_ignore_pfc_rx(uint8 lchip, uint32 gport, uint8 pri_class, uint8 enable, uint8* pfc_en)
{
    uint8  is_pfc = 0;
    uint8  dp_id = 0;
    uint8 sub_chan = 0;
    uint16 lport = 0;
    uint32 cmd = 0;
    uint32 tmp_mac_id = 0;
    uint32 rx_pause_type = 0;
    ctc_port_fc_prop_t p_fc_prop;
    ds_t ds;
    uint32 txaqm_port_id = 0;
    sys_port_info_t port_info = {0};

    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_PARAM, "ignore pfc rx: gport=%d, pri_class=%d, enable=%d\n", gport, pri_class, enable);
    SYS_MAP_CTC_GPORT_TO_DRV_LPORT_WITH_CHECK(gport, lchip, lport);
    if (!SYS_GPORT_IS_NETWORK_PORT(gport))
    {
        return CTC_E_INVALID_PORT;
    }
    CTC_ERROR_RETURN(sys_usw_port_api_get_com_info(lchip, lport, 0, &port_info));
    tmp_mac_id = port_info.mac_id;
    sub_chan = port_info.sub_chan_id;
    dp_id = port_info.dp_id;
    SYS_QOS_LCHIP_CONVERT(lchip, port_info.pp_id);

    if (tmp_mac_id >= SYS_CPU_MAC_ID_MIN && tmp_mac_id <= SYS_CPU_MAC_ID_MAX)
    {
        cmd = DRV_IOR(NetRxPauseReqCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_DP_EN(cmd, dp_id), &ds));
        rx_pause_type = GetNetRxPauseReqCtl(V, cfgCpuMacPauseType_f, &ds);
        is_pfc = CTC_IS_BIT_SET(rx_pause_type, ((tmp_mac_id - SYS_CPU_MAC_ID_MIN) & 0x1));
    }
    else
    {
        cmd = DRV_IOR(DsNetRxChanToPortMap_t, DsNetRxChanToPortMap_portId_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, sub_chan, DRV_CMD_DP_EN(cmd, dp_id), &txaqm_port_id));
        cmd = DRV_IOR(NetRxPauseReqCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_DP_EN(cmd, dp_id), &ds));
        rx_pause_type = GetNetRxPauseReqCtl(V, netRxPauseType_f, &ds);
        is_pfc = CTC_IS_BIT_SET(rx_pause_type, txaqm_port_id);
    }

    *pfc_en = is_pfc;
    sal_memset(&p_fc_prop, 0, sizeof(p_fc_prop));
    p_fc_prop.gport = gport;
    p_fc_prop.dir = CTC_INGRESS;
    p_fc_prop.is_pfc = is_pfc;
    p_fc_prop.priority_class = pri_class;
    p_fc_prop.enable = enable ? FALSE : TRUE;
	CTC_ERROR_RETURN(SYS_CB(SYS_CB_QOS_SET_FLOW_CONTROL, lchip, (void*)&p_fc_prop, 1));
    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "ignore pfc rx: p_fc_prop.gport=%d, p_fc_prop.dir=%d, p_fc_prop.is_pfc=%d, "
                                    "p_fc_prop.priority_class=%d,p_fc_prop.enable=%d\n", p_fc_prop.gport, p_fc_prop.dir,
                                    p_fc_prop.is_pfc,p_fc_prop.priority_class,p_fc_prop.enable);
    return CTC_E_NONE;
}

STATIC int32
_sys_at_qos_fcdl_recover_drop_pkt(uint8 lchip, uint32 gport, uint8 pri_class, uint8 enable, uint8 pfc_en)
{
    ctc_qos_queue_id_t queue;
    sys_queue_node_t* p_que_node = NULL;
    uint32 chan_id = 0;
    uint16 queue_id = 0;
    uint16 sub_chan = 0;
    sys_usw_dmps_port_info_t dmps_port_info = {0};


    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_PARAM, "drop pkt: gport=%d, pri_class=%d, enable=%d, pfc_en=%d\n", gport, pri_class, enable, pfc_en);
    dmps_port_info.gport = gport;
    CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_CHAN_ID, &chan_id));
    if (SYS_COMMON_USELESS_CHANNEL == chan_id)
    {
        return CTC_E_INVALID_PORT;
    }

    sal_memset(&queue, 0, sizeof(queue));
    queue.gport = gport;
    queue.queue_id = pri_class;
    queue.queue_type = CTC_QUEUE_TYPE_NETWORK_EGRESS;
    CTC_ERROR_RETURN(sys_at_queue_get_queue_id(lchip,  &queue, &queue_id));
    p_que_node = ctc_vector_get(p_usw_queue_master[lchip]->queue_vec, queue_id);
    if (NULL == p_que_node)
    {
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Entry not exist \n");
        return CTC_E_NOT_EXIST;
    }

    CTC_ERROR_RETURN(sys_at_get_sub_channel_by_channel(lchip, chan_id, &sub_chan));

    if (enable) /*store profile*/
    {
        CTC_ERROR_RETURN(_sys_at_queue_store_buffer_thrd(lchip, queue_id, chan_id, sub_chan, pfc_en));
    }
    else
    {
        CTC_ERROR_RETURN(_sys_at_queue_restore_buffer_thrd(lchip, queue_id, chan_id, sub_chan, pfc_en));
    }

    return CTC_E_NONE;
}

int32
sys_at_qos_fcdl_recover(uint8 lchip, uint32 gport, uint8 pri_class, uint8 enable)
{
    uint8  pfc_en = 0;

    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_PARAM, "recover gport=%d, pri_class=%d, enable=%d\n", gport, pri_class, enable);

    /*disable flowctl*/
    CTC_ERROR_RETURN(_sys_at_qos_fcdl_recover_ignore_pfc_rx(lchip, gport, pri_class, enable, &pfc_en));

    /*drop incoming packets*/
    if(p_usw_queue_master[lchip]->fcdl_action == CTC_QOS_FCDL_ACTION_DROP)
    {
        CTC_ERROR_RETURN(_sys_at_qos_fcdl_recover_drop_pkt(lchip, gport, pri_class, enable, pfc_en));
    }
    return CTC_E_NONE;
}

int32
_sys_at_qos_set_fcdl_detect_cpu_mac(uint8 lchip, uint32 mac_id, ctc_qos_resrc_fcdl_detect_t *p_fcdl)
{
    uint8 enable                    = 0;
    uint8 prio_class                = 0;
    uint8 loop                      = 0;
    uint16 step                     = 0;
    uint32 cmd                      = 0;

    Sgmac0RxPauseCfg_m sgmac_rx_pause_ctl;
    sal_memset(&sgmac_rx_pause_ctl, 0, sizeof(sgmac_rx_pause_ctl));

    if ((mac_id - SYS_CPU_MAC_ID_MIN) >= 2)
    {
        lchip = SYS_PP_BASE(lchip) + SYS_PP_NUM(lchip) / 2;
    }
    else
    {
        lchip = SYS_PP_BASE(lchip);
    }
    step = (Sgmac1RxPauseCfg_t - Sgmac0RxPauseCfg_t) * ((mac_id - SYS_CPU_MAC_ID_MIN) % 2);
    cmd = DRV_IOR(Sgmac0RxPauseCfg_t + step, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &sgmac_rx_pause_ctl));
    if (p_fcdl->enable)
    {
        if (CTC_MAX_FCDL_DETECT_NUM == p_fcdl->valid_num)/*config 2 cos together*/
        {
            SetSgmac0RxPauseCfg(V, cfgSgmac0RxPauseLockDetectEn0_f, &sgmac_rx_pause_ctl, p_fcdl->enable);
            SetSgmac0RxPauseCfg(V, cfgSgmac0RxPauseLockDetectEn1_f, &sgmac_rx_pause_ctl, p_fcdl->enable);
            SetSgmac0RxPauseCfg(V, cfgSgmac0RxPauseLockDetectCos0_f, &sgmac_rx_pause_ctl, p_fcdl->priority_class[0]);
            SetSgmac0RxPauseCfg(V, cfgSgmac0RxPauseLockDetectCos1_f, &sgmac_rx_pause_ctl, p_fcdl->priority_class[1]);
            SetSgmac0RxPauseCfg(V, cfgSgmac0RxPauseLockDetectTimer0_f, &sgmac_rx_pause_ctl, p_fcdl->detect_mult);
            SetSgmac0RxPauseCfg(V, cfgSgmac0RxPauseLockDetectTimer1_f, &sgmac_rx_pause_ctl, p_fcdl->detect_mult);
        }
        else
        {
            for (loop = 0; loop < CTC_MAX_FCDL_DETECT_NUM; loop++)
            {
                enable = GetSgmac0RxPauseCfg(V, cfgSgmac0RxPauseLockDetectEn0_f + loop, &sgmac_rx_pause_ctl);
                if (!enable)
                {
                    SetSgmac0RxPauseCfg(V, cfgSgmac0RxPauseLockDetectEn0_f + loop, &sgmac_rx_pause_ctl, p_fcdl->enable);
                    SetSgmac0RxPauseCfg(V, cfgSgmac0RxPauseLockDetectCos0_f + loop, &sgmac_rx_pause_ctl, p_fcdl->priority_class[0]);
                    SetSgmac0RxPauseCfg(V, cfgSgmac0RxPauseLockDetectTimer0_f + loop, &sgmac_rx_pause_ctl, p_fcdl->detect_mult);
                    break;
                }
            }

            if (loop == CTC_MAX_FCDL_DETECT_NUM)
            {
                return CTC_E_NO_RESOURCE;
            }
        }
    }
    else
    {
        if (CTC_MAX_FCDL_DETECT_NUM == p_fcdl->valid_num)
        {
            SetSgmac0RxPauseCfg(V, cfgSgmac0RxPauseLockDetectEn0_f, &sgmac_rx_pause_ctl, p_fcdl->enable);
            SetSgmac0RxPauseCfg(V, cfgSgmac0RxPauseLockDetectEn1_f, &sgmac_rx_pause_ctl, p_fcdl->enable);
        }
        else
        {
            for (loop = 0; loop < CTC_MAX_FCDL_DETECT_NUM; loop++)
            {
                enable = GetSgmac0RxPauseCfg(V, cfgSgmac0RxPauseLockDetectEn0_f + loop, &sgmac_rx_pause_ctl);
                prio_class = GetSgmac0RxPauseCfg(V, cfgSgmac0RxPauseLockDetectCos0_f + loop, &sgmac_rx_pause_ctl);

                if (enable && prio_class == p_fcdl->priority_class[0])
                {
                    SetSgmac0RxPauseCfg(V, cfgSgmac0RxPauseLockDetectEn0_f + loop, &sgmac_rx_pause_ctl, p_fcdl->enable);
                    break;
                }
            }

            if (loop == CTC_MAX_FCDL_DETECT_NUM)
            {
                return CTC_E_INVALID_PARAM;
            }
        }
    }

    cmd = DRV_IOW(Sgmac0RxPauseCfg_t + step, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &sgmac_rx_pause_ctl));

    return CTC_E_NONE;
}

int32
_sys_at_qos_get_fcdl_detect_cpu_mac(uint8 lchip, uint32 mac_id, ctc_qos_resrc_fcdl_detect_t *p_fcdl)
{
    uint16 step                                  = 0;
    uint32 cmd                                   = 0;
    uint8 value[CTC_MAX_FCDL_DETECT_NUM]         = {0};
    uint8 detect_mult[CTC_MAX_FCDL_DETECT_NUM]   = {0};
    uint8 prio_class[CTC_MAX_FCDL_DETECT_NUM]    = {0};
    uint8 loop                                   = 0;
    Sgmac0RxPauseCfg_m sgmac_rx_pause_ctl;

    sal_memset(&sgmac_rx_pause_ctl, 0, sizeof(sgmac_rx_pause_ctl));
    if ((mac_id - SYS_CPU_MAC_ID_MIN) >= 2)
    {
        lchip = SYS_PP_BASE(lchip) + SYS_PP_NUM(lchip) / 2;
    }
    else
    {
        lchip = SYS_PP_BASE(lchip);
    }
    step = (Sgmac1RxPauseCfg_t - Sgmac0RxPauseCfg_t) * ((mac_id - SYS_CPU_MAC_ID_MIN) % 2);
    cmd = DRV_IOR(Sgmac0RxPauseCfg_t + step, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &sgmac_rx_pause_ctl));
    for (loop = 0; loop < CTC_MAX_FCDL_DETECT_NUM; loop++)
    {
        value[loop] = GetSgmac0RxPauseCfg(V, cfgSgmac0RxPauseLockDetectEn0_f + loop, &sgmac_rx_pause_ctl);
        detect_mult[loop] = GetSgmac0RxPauseCfg(V, cfgSgmac0RxPauseLockDetectTimer0_f + loop, &sgmac_rx_pause_ctl);
        prio_class[loop] = GetSgmac0RxPauseCfg(V, cfgSgmac0RxPauseLockDetectCos0_f + loop, &sgmac_rx_pause_ctl);
        if (value[loop])
        {
            p_fcdl->valid_num++;
        }
    }

    if(value[0] && prio_class[0] == p_fcdl->priority_class[0])
    {
        p_fcdl->enable = 1;
        p_fcdl->detect_mult = detect_mult[0];
    }
    else if(value[1] && prio_class[1] == p_fcdl->priority_class[0])
    {
        p_fcdl->enable = 1;
        p_fcdl->detect_mult = detect_mult[1];
    }
    return CTC_E_NONE;
}

int32
_sys_at_qos_set_fcdl_detect_network(uint8 lchip, uint32 mac_id, ctc_qos_resrc_fcdl_detect_t *p_fcdl)
{
    uint8 enable = 0;
    uint8 prio_class = 0;
    uint32 pp_id = 0;
    uint8 loop = 0;
    uint16 step = 0;
    uint32 cmd = 0;
    uint32 index = 0;
    sys_usw_dmps_port_info_t dmps_port_info = {0};
    McMacPauseRxCtl_m mac_rx_pause_ctl;
    sal_memset(&mac_rx_pause_ctl, 0, sizeof(McMacPauseRxCtl_m));

    dmps_port_info.gport = p_fcdl->gport;
    CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_PP_ID, &pp_id));
    SYS_QOS_LCHIP_CONVERT(lchip, pp_id);

    step = (McMacPauseRxCtl_mcMacPauseRxCfg_1_cfgMcMacRxPauseLockDetectEn0_f - McMacPauseRxCtl_mcMacPauseRxCfg_0_cfgMcMacRxPauseLockDetectEn0_f) * (mac_id % MCHIP_CAP(SYS_CAP_MAC_NUM_PER_QM));
    cmd = DRV_IOR(McMacPauseRxCtl_t, DRV_ENTRY_FLAG);
    index = (mac_id / MCHIP_CAP(SYS_CAP_MAC_NUM_PER_QM)) % DRV_TABLE_MAX_INDEX(lchip, McMacPauseRxCtl_t);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_PP_EN(cmd), &mac_rx_pause_ctl));
    if (p_fcdl->enable)
    {
        if (CTC_MAX_FCDL_DETECT_NUM == p_fcdl->valid_num) /*config 2 cos together*/
        {
            SetMcMacPauseRxCtl(V, mcMacPauseRxCfg_0_cfgMcMacRxPauseLockDetectEn0_f + step, &mac_rx_pause_ctl, p_fcdl->enable);
            SetMcMacPauseRxCtl(V, mcMacPauseRxCfg_0_cfgMcMacRxPauseLockDetectEn1_f + step, &mac_rx_pause_ctl, p_fcdl->enable);
            SetMcMacPauseRxCtl(V, mcMacPauseRxCfg_0_cfgMcMacRxPauseLockDetectCos0_f + step, &mac_rx_pause_ctl, p_fcdl->priority_class[0]);
            SetMcMacPauseRxCtl(V, mcMacPauseRxCfg_0_cfgMcMacRxPauseLockDetectCos1_f + step, &mac_rx_pause_ctl, p_fcdl->priority_class[1]);
            SetMcMacPauseRxCtl(V, mcMacPauseRxCfg_0_cfgMcMacRxPauseLockDetectTimer0_f + step, &mac_rx_pause_ctl, p_fcdl->detect_mult);
            SetMcMacPauseRxCtl(V, mcMacPauseRxCfg_0_cfgMcMacRxPauseLockDetectTimer1_f + step, &mac_rx_pause_ctl, p_fcdl->detect_mult);
        }
        else
        {
            for (loop = 0; loop < CTC_MAX_FCDL_DETECT_NUM; loop++)
            {
                if (loop)
                {
                    enable = GetMcMacPauseRxCtl(V, mcMacPauseRxCfg_0_cfgMcMacRxPauseLockDetectEn1_f + step, &mac_rx_pause_ctl);
                    if (!enable)
                    {
                        SetMcMacPauseRxCtl(V, mcMacPauseRxCfg_0_cfgMcMacRxPauseLockDetectEn1_f + step, &mac_rx_pause_ctl, p_fcdl->enable);
                        SetMcMacPauseRxCtl(V, mcMacPauseRxCfg_0_cfgMcMacRxPauseLockDetectCos1_f + step, &mac_rx_pause_ctl, p_fcdl->priority_class[0]);
                        SetMcMacPauseRxCtl(V, mcMacPauseRxCfg_0_cfgMcMacRxPauseLockDetectTimer1_f + step, &mac_rx_pause_ctl, p_fcdl->detect_mult);
                        break;
                    }
                }
                else
                {
                    enable = GetMcMacPauseRxCtl(V, mcMacPauseRxCfg_0_cfgMcMacRxPauseLockDetectEn0_f + step, &mac_rx_pause_ctl);
                    if (!enable)
                    {
                        SetMcMacPauseRxCtl(V, mcMacPauseRxCfg_0_cfgMcMacRxPauseLockDetectEn0_f + step, &mac_rx_pause_ctl, p_fcdl->enable);
                        SetMcMacPauseRxCtl(V, mcMacPauseRxCfg_0_cfgMcMacRxPauseLockDetectCos0_f + step, &mac_rx_pause_ctl, p_fcdl->priority_class[0]);
                        SetMcMacPauseRxCtl(V, mcMacPauseRxCfg_0_cfgMcMacRxPauseLockDetectTimer0_f + step, &mac_rx_pause_ctl, p_fcdl->detect_mult);
                        break;
                    }
                }
            }

            if (loop == CTC_MAX_FCDL_DETECT_NUM)
            {
                return CTC_E_NO_RESOURCE;
            }
        }
    }
    else
    {
        if (CTC_MAX_FCDL_DETECT_NUM == p_fcdl->valid_num)
        {
            SetMcMacPauseRxCtl(V, mcMacPauseRxCfg_0_cfgMcMacRxPauseLockDetectEn0_f + step, &mac_rx_pause_ctl, p_fcdl->enable);
            SetMcMacPauseRxCtl(V, mcMacPauseRxCfg_0_cfgMcMacRxPauseLockDetectEn1_f + step, &mac_rx_pause_ctl, p_fcdl->enable);
        }
        else
        {
            for (loop = 0; loop < CTC_MAX_FCDL_DETECT_NUM; loop++)
            {
                if (loop)
                {
                    enable = GetMcMacPauseRxCtl(V, mcMacPauseRxCfg_0_cfgMcMacRxPauseLockDetectEn1_f + step, &mac_rx_pause_ctl);
                    prio_class = GetMcMacPauseRxCtl(V, mcMacPauseRxCfg_0_cfgMcMacRxPauseLockDetectCos1_f + step, &mac_rx_pause_ctl);

                    if (enable && prio_class == p_fcdl->priority_class[0])
                    {
                        SetMcMacPauseRxCtl(V, mcMacPauseRxCfg_0_cfgMcMacRxPauseLockDetectEn1_f + step, &mac_rx_pause_ctl, p_fcdl->enable);
                        break;
                    }
                }
                else
                {
                    enable = GetMcMacPauseRxCtl(V, mcMacPauseRxCfg_0_cfgMcMacRxPauseLockDetectEn0_f + step, &mac_rx_pause_ctl);
                    prio_class = GetMcMacPauseRxCtl(V, mcMacPauseRxCfg_0_cfgMcMacRxPauseLockDetectCos0_f + step, &mac_rx_pause_ctl);

                    if (enable && prio_class == p_fcdl->priority_class[0])
                    {
                        SetMcMacPauseRxCtl(V, mcMacPauseRxCfg_0_cfgMcMacRxPauseLockDetectEn0_f + step, &mac_rx_pause_ctl, p_fcdl->enable);
                        break;
                    }
                }
            }

            if (loop == CTC_MAX_FCDL_DETECT_NUM)
            {
                return CTC_E_INVALID_PARAM;
            }
        }
    }

    cmd = DRV_IOW(McMacPauseRxCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_PP_EN(cmd), &mac_rx_pause_ctl));

    return CTC_E_NONE;
}

int32
_sys_at_qos_get_fcdl_detect_network(uint8 lchip, uint32 mac_id, ctc_qos_resrc_fcdl_detect_t *p_fcdl)
{
    uint32 pp_id = 0;
    uint16 step                                  = 0;
    uint32 cmd                                   = 0;
    uint8 value[CTC_MAX_FCDL_DETECT_NUM]         = {0};
    uint8 detect_mult[CTC_MAX_FCDL_DETECT_NUM]   = {0};
    uint8 prio_class[CTC_MAX_FCDL_DETECT_NUM]    = {0};
    uint8 loop = 0;
    uint32 index = 0;
    sys_usw_dmps_port_info_t dmps_port_info = {0};
    McMacPauseRxCtl_m mac_rx_pause_ctl;
    sal_memset(&mac_rx_pause_ctl, 0, sizeof(McMacPauseRxCtl_m));

    dmps_port_info.gport = p_fcdl->gport;
    CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_PP_ID, &pp_id));
    SYS_QOS_LCHIP_CONVERT(lchip, pp_id);

    index = (mac_id / MCHIP_CAP(SYS_CAP_MAC_NUM_PER_QM)) % DRV_TABLE_MAX_INDEX(lchip, McMacPauseRxCtl_t);
    step = (McMacPauseRxCtl_mcMacPauseRxCfg_1_cfgMcMacRxPauseLockDetectEn0_f - McMacPauseRxCtl_mcMacPauseRxCfg_0_cfgMcMacRxPauseLockDetectEn0_f) * (mac_id % MCHIP_CAP(SYS_CAP_MAC_NUM_PER_QM));
    cmd = DRV_IOR(McMacPauseRxCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_PP_EN(cmd), &mac_rx_pause_ctl));
    for (loop = 0; loop < CTC_MAX_FCDL_DETECT_NUM; loop++)
    {
        if (loop)
        {
            value[loop] = GetMcMacPauseRxCtl(V, mcMacPauseRxCfg_0_cfgMcMacRxPauseLockDetectEn1_f + step, &mac_rx_pause_ctl);
            detect_mult[loop] = GetMcMacPauseRxCtl(V, mcMacPauseRxCfg_0_cfgMcMacRxPauseLockDetectTimer1_f + step, &mac_rx_pause_ctl);
            prio_class[loop] = GetMcMacPauseRxCtl(V, mcMacPauseRxCfg_0_cfgMcMacRxPauseLockDetectCos1_f + step, &mac_rx_pause_ctl);
        }
        else
        {
            value[loop] = GetMcMacPauseRxCtl(V, mcMacPauseRxCfg_0_cfgMcMacRxPauseLockDetectEn0_f + step, &mac_rx_pause_ctl);
            detect_mult[loop] = GetMcMacPauseRxCtl(V, mcMacPauseRxCfg_0_cfgMcMacRxPauseLockDetectTimer0_f + step, &mac_rx_pause_ctl);
            prio_class[loop] = GetMcMacPauseRxCtl(V, mcMacPauseRxCfg_0_cfgMcMacRxPauseLockDetectCos0_f + step, &mac_rx_pause_ctl);
        }

        if (value[loop])
        {
            p_fcdl->valid_num++;
        }
    }

    if(value[0] && prio_class[0] == p_fcdl->priority_class[0])
    {
        p_fcdl->enable = 1;
        p_fcdl->detect_mult = detect_mult[0];
    }
    else if(value[1] && prio_class[1] == p_fcdl->priority_class[0])
    {
        p_fcdl->enable = 1;
        p_fcdl->detect_mult = detect_mult[1];
    }
    return CTC_E_NONE;
}

int32
sys_at_qos_fcdl_detect_mac(uint8 lchip, void* p_fcdl_tmp, uint8 is_get)
{
    uint32 mac_id = 0;
    ctc_qos_resrc_fcdl_detect_t* p_fcdl = (ctc_qos_resrc_fcdl_detect_t*)p_fcdl_tmp;
    sys_usw_dmps_port_info_t dmps_port_info = {0};
    dmps_port_info.gport = p_fcdl->gport;
    CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_MAC_STATS_ID, (void *)&mac_id));
    if (SYS_DATAPATH_USELESS_MAC == mac_id)
    {
        return CTC_E_INVALID_CONFIG;
    }
    if (mac_id >= SYS_CPU_MAC_ID_MIN && mac_id <= SYS_CPU_MAC_ID_MAX)
    {
        if (is_get)
        {
            CTC_ERROR_RETURN(_sys_at_qos_get_fcdl_detect_cpu_mac(lchip, mac_id, p_fcdl));
        }
        else
        {
            CTC_ERROR_RETURN(_sys_at_qos_set_fcdl_detect_cpu_mac(lchip, mac_id, p_fcdl));
        }
    }
    else
    {
        if (is_get)
        {
            CTC_ERROR_RETURN(_sys_at_qos_get_fcdl_detect_network(lchip, mac_id, p_fcdl));
        }
        else
        {
            CTC_ERROR_RETURN(_sys_at_qos_set_fcdl_detect_network(lchip, mac_id, p_fcdl));
        }
    }
    return CTC_E_NONE;
}

int32
sys_at_queue_set_resrc(uint8 lchip, ctc_qos_resrc_t* p_resrc)
{
    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    CTC_PTR_VALID_CHECK(p_resrc);

    switch (p_resrc->cfg_type)
    {
    case CTC_QOS_RESRC_CFG_POOL_CLASSIFY:
        CTC_ERROR_RETURN(sys_at_qos_set_resrc_classify_pool(lchip, &p_resrc->u.pool));
        break;

    case CTC_QOS_RESRC_CFG_PORT_MIN:
        CTC_MAX_VALUE_CHECK(p_resrc->u.port_min.threshold, SYS_AT_MAX_GUARANTEE);
        CTC_ERROR_RETURN(sys_at_queue_set_port_min(lchip, &p_resrc->u.port_min));
        break;

    case CTC_QOS_RESRC_CFG_QUEUE_DROP:
        return CTC_E_NOT_SUPPORT;

    case CTC_QOS_RESRC_CFG_FLOW_CTL:
        CTC_ERROR_RETURN(sys_at_qos_fc_add_profile(lchip, &p_resrc->u.flow_ctl));
        break;

    case CTC_QOS_RESRC_CFG_FCDL_DETECT:
        CTC_ERROR_RETURN(sys_usw_qos_set_fcdl_detect(lchip, &p_resrc->u.fcdl_detect));
        break;

    case CTC_QOS_RESRC_CFG_QUEUE_MIN:
        CTC_ERROR_RETURN(sys_at_queue_set_queue_min(lchip, p_resrc->u.queue_min));
        break;

    case CTC_QOS_RESRC_CFG_OBM_POOL:
        CTC_ERROR_RETURN(sys_usw_queue_set_obm_pool(lchip, p_resrc->u.obm_pool));
        break;

    default:
        return CTC_E_INVALID_PARAM;
    }

    return CTC_E_NONE;
}

int32
sys_at_queue_get_resrc(uint8 lchip, ctc_qos_resrc_t* p_resrc)
{
    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    CTC_PTR_VALID_CHECK(p_resrc);

    switch (p_resrc->cfg_type)
    {
    case CTC_QOS_RESRC_CFG_POOL_CLASSIFY:
        CTC_ERROR_RETURN(sys_at_qos_get_resrc_classify_pool(lchip, &p_resrc->u.pool));
        break;

    case CTC_QOS_RESRC_CFG_PORT_MIN:
        CTC_ERROR_RETURN(sys_at_queue_get_port_min(lchip, &p_resrc->u.port_min));
        break;

    case CTC_QOS_RESRC_CFG_QUEUE_DROP:
        return CTC_E_NOT_SUPPORT;

    case CTC_QOS_RESRC_CFG_FLOW_CTL:
        CTC_ERROR_RETURN(sys_at_qos_fc_get_profile(lchip, &p_resrc->u.flow_ctl));
        break;

    case CTC_QOS_RESRC_CFG_FCDL_DETECT:
        CTC_ERROR_RETURN(sys_usw_qos_get_fcdl_detect(lchip, &p_resrc->u.fcdl_detect));
        break;

    case CTC_QOS_RESRC_CFG_QUEUE_MIN:
        CTC_ERROR_RETURN(sys_at_queue_get_queue_min(lchip, &p_resrc->u.queue_min));
        break;

    case CTC_QOS_RESRC_CFG_OBM_POOL:
        CTC_ERROR_RETURN(sys_usw_queue_get_obm_pool(lchip, &p_resrc->u.obm_pool));
        break;

    default:
        return CTC_E_INVALID_PARAM;
    }

    return CTC_E_NONE;
}

int32
sys_at_queue_query_pool_stats(uint8 lchip, ctc_qos_resrc_pool_stats_t* p_stats)
{
    CTC_PTR_VALID_CHECK(p_stats);
    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    return sys_at_resrc_query_pool_stats(lchip, p_stats);
}

int32
sys_at_qos_resrc_mgr_en(uint8 lchip, uint8 enable)
{
    uint32 cmd        = 0;
    uint32 field_val  = 0;
    ds_t ds;
    field_val = enable ? 1 : 0;

    cmd = DRV_IOR(IrmMiscCtlUc_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
    SetIrmMiscCtlUc(V, resourceCheckEn_f, &ds, field_val);
    cmd = DRV_IOW(IrmMiscCtlUc_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));

    cmd = DRV_IOR(IrmMiscCtlMc_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
    SetIrmMiscCtlMc(V, resourceCheckEn_f, &ds, field_val);
    cmd = DRV_IOW(IrmMiscCtlMc_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));

    cmd = DRV_IOR(ErmMiscCtlUc_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
    SetErmMiscCtlUc(V, resourceCheckEn_f, &ds, field_val);
    cmd = DRV_IOW(ErmMiscCtlUc_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));

    cmd = DRV_IOR(ErmMiscCtlMc_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
    SetErmMiscCtlUc(V, resourceCheckEn_f, &ds, field_val);
    cmd = DRV_IOW(ErmMiscCtlMc_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
    return CTC_E_NONE;
}

int32
sys_at_queue_drop_init(uint8 lchip, void *p_glb_parm)
{
    int32 ret = CTC_E_NONE;
    uint32 cmd = 0;
    EpePktProcCtl_m EpePktProcCtl;
    BufferStoreCtl_m bufstore_ctl;
    ds_t ds;
    ctc_qos_global_cfg_t * p_glb_cfg = NULL;
    p_glb_cfg = (ctc_qos_global_cfg_t *)p_glb_parm;

    p_usw_queue_master[lchip]->resrc_check_mode = 0;

    cmd = DRV_IOR(EpePktProcCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &EpePktProcCtl));
    SetEpePktProcCtl(V, queueDepthThrd_f, &EpePktProcCtl, 0x1FFFF);
    cmd = DRV_IOW(EpePktProcCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &EpePktProcCtl));
    cmd = DRV_IOR(MapPktCfg_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
    SetMapPktCfg(V, ermXfcTimerEn_f, &ds, 1);
    SetMapPktCfg(V, mrmXfcTimerEn_f, &ds, 1);
    SetMapPktCfg(V, xfcPktProcEn_f, &ds, 1);
    cmd = DRV_IOW(MapPktCfg_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));

    cmd = DRV_IOR(BufferStoreCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &bufstore_ctl));
    SetBufferStoreCtl(V, headroomCheckMode_f, &bufstore_ctl, 1);
    cmd = DRV_IOW(BufferStoreCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &bufstore_ctl));

    cmd = DRV_IOR(McQWriteSpanOnDropCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
    SetMcQWriteSpanOnDropCtl(V, sodDest_channelId_f, &ds, 63); /*default disable*/
    cmd = DRV_IOW(McQWriteSpanOnDropCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));

    CTC_ERROR_RETURN(sys_at_qos_resrc_mgr_init(lchip, p_glb_parm));

    CTC_ERROR_GOTO(sys_at_queue_drop_init_profile(lchip, p_glb_cfg), ret, error0);
    CTC_ERROR_GOTO(sys_usw_queue_drop_ecn_init(lchip, 0), ret, error1);

    p_usw_queue_master[lchip]->igs_resrc_mode[0] = p_glb_cfg->resrc_pool.igs_pool_mode;
    p_usw_queue_master[lchip]->igs_resrc_mode[1] = p_glb_cfg->resrc_pool2.igs_pool_mode;
    p_usw_queue_master[lchip]->egs_resrc_mode[0] = p_glb_cfg->resrc_pool.egs_pool_mode;
    p_usw_queue_master[lchip]->egs_resrc_mode[1] = p_glb_cfg->resrc_pool2.egs_pool_mode;
    p_usw_queue_master[lchip]->fcdl_info = mem_malloc(MEM_QUEUE_MODULE, SYS_USW_MAX_PORT_NUM_PER_CHIP * sizeof(sys_fcdl_info_t));
    if (NULL == p_usw_queue_master[lchip]->fcdl_info)
    {
        ret = CTC_E_NO_MEMORY;
        goto error1;

    }

    p_usw_queue_master[lchip]->buffer_info_vec = ctc_vector_init(MCHIP_CAP(SYS_CAP_CHANNEL_NUM)/16, 16);
    if (NULL == p_usw_queue_master[lchip]->buffer_info_vec)
    {
        ret = CTC_E_NO_MEMORY;
        goto error2;
    }

    sal_memset(p_usw_queue_master[lchip]->fcdl_info, 0, SYS_USW_MAX_PORT_NUM_PER_CHIP * sizeof(sys_fcdl_info_t));
    CTC_ERROR_GOTO(SYS_CB_REGISTER(lchip, SYS_CB_QOS_FCDL_SET_RECOVER_TIMER, sys_usw_qos_fcdl_timer_en), ret, error2);
    sys_usw_interrupt_register_event_cb(lchip, CTC_EVENT_FCDL_DETECT, _sys_usw_qos_fcdl_event_cb);
    return CTC_E_NONE;
error2:
    mem_free(p_usw_queue_master[lchip]->fcdl_info);
error1:
    sys_at_queue_drop_deinit_profile(lchip);
error0:
    return ret;
}

STATIC int32
_sys_at_queue_drop_free_node_data(void* node_data, void* user_data)
{
    sys_qos_buffer_info_t* p_buffer_info = (sys_qos_buffer_info_t*)node_data;
    mem_free(p_buffer_info);
    return CTC_E_NONE;
}

int32
sys_at_queue_drop_deinit(uint8 lchip)
{
    sys_at_queue_drop_deinit_profile(lchip);
    sys_usw_interrupt_register_event_cb(lchip, CTC_EVENT_FCDL_DETECT, NULL);
    SYS_CB_REGISTER(lchip, SYS_CB_QOS_FCDL_SET_RECOVER_TIMER, NULL);
    if(p_usw_queue_master[lchip]->p_recover_timer)
    {
        sal_timer_destroy(p_usw_queue_master[lchip]->p_recover_timer);
        p_usw_queue_master[lchip]->p_recover_timer = NULL;
    }
    mem_free(p_usw_queue_master[lchip]->fcdl_info);
    if (p_usw_queue_master[lchip]->buffer_info_vec)
    {
        ctc_vector_traverse(p_usw_queue_master[lchip]->buffer_info_vec, (vector_traversal_fn)_sys_at_queue_drop_free_node_data, NULL);
        ctc_vector_release(p_usw_queue_master[lchip]->buffer_info_vec);
    }
    return CTC_E_NONE;
}

int32
sys_at_qos_drop_dump_status(uint8 lchip)
{
    uint32 cmd = 0;
    DsErmScThrdUc_m erm_sc_thrd;
    DsErmScThrdMc_m erm_sc_thrd_mc;
    DsErmMiscThrdUc_m erm_misc_thrd;
    DsErmMiscThrdMc_m erm_misc_thrd_mc;
    DsIrmScThrdUc_m irm_sc_thrd;
    DsIrmScThrdMc_m irm_sc_thrd_mc;
    DsIrmMiscThrdUc_m irm_misc_thrd;
    DsIrmMiscThrdMc_m irm_misc_thrd_mc;

    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "-------------------------Queue Drop-----------------------\n");

    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "%-30s: %d\n", "Total WRED drop profile", p_usw_queue_master[lchip]->p_drop_wred_profile_pool->max_count);
    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "%-30s: %d\n","--Used count", p_usw_queue_master[lchip]->p_drop_wred_profile_pool->count);
    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "\n");

    cmd = DRV_IOR(DsErmScThrdUc_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &erm_sc_thrd));
    cmd = DRV_IOR(DsIrmScThrdUc_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &irm_sc_thrd));
    cmd = DRV_IOR(DsErmMiscThrdUc_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &erm_misc_thrd));
    cmd = DRV_IOR(DsIrmMiscThrdUc_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &irm_misc_thrd));

    cmd = DRV_IOR(DsErmScThrdMc_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &erm_sc_thrd_mc));
    cmd = DRV_IOR(DsIrmScThrdMc_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &irm_sc_thrd_mc));
    cmd = DRV_IOR(DsErmMiscThrdMc_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &erm_misc_thrd_mc));
    cmd = DRV_IOR(DsIrmMiscThrdMc_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &irm_misc_thrd_mc));
    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-30s: %d\n", "Ingress UC resrc mode", p_usw_queue_master[lchip]->igs_resrc_mode[0]);
    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-30s: %d\n", "--Total thrd", GetDsIrmMiscThrdUc(V, totalThrd_f, &irm_misc_thrd));
    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-30s: %d\n", "--SC0 thrd", GetDsIrmScThrdUc(V, g_0_scThrd_f, &irm_sc_thrd));
    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-30s: %d\n", "--SC1 thrd", GetDsIrmScThrdUc(V, g_1_scThrd_f, &irm_sc_thrd));
    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-30s: %d\n", "--SC2 thrd", GetDsIrmScThrdUc(V, g_2_scThrd_f, &irm_sc_thrd));
    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-30s: %d\n", "--SC3 thrd", GetDsIrmScThrdUc(V, g_3_scThrd_f, &irm_sc_thrd));
    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-30s: %d\n", "Egress UC resrc mode", p_usw_queue_master[lchip]->egs_resrc_mode[0]);
    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-30s: %d\n", "--Total thrd", GetDsErmMiscThrdUc(V, totalThrd_f, &erm_misc_thrd));
    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-30s: %d\n", "--SC0 thrd", GetDsErmScThrdUc(V, g_0_scThrd_f, &erm_sc_thrd));
    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-30s: %d\n", "--SC1 thrd", GetDsErmScThrdUc(V, g_1_scThrd_f, &erm_sc_thrd));
    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-30s: %d\n", "--SC2 thrd", GetDsErmScThrdUc(V, g_2_scThrd_f, &erm_sc_thrd));
    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-30s: %d\n", "--SC3 thrd", GetDsErmScThrdUc(V, g_3_scThrd_f, &erm_sc_thrd));

    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-30s: %d\n", "Ingress NON-UC resrc mode", p_usw_queue_master[lchip]->igs_resrc_mode[1]);
    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-30s: %d\n", "--Total thrd", GetDsIrmMiscThrdMc(V, totalThrd_f, &irm_misc_thrd_mc));
    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-30s: %d\n", "--SC0 thrd", GetDsIrmScThrdMc(V, g_0_scThrd_f, &irm_sc_thrd_mc));
    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-30s: %d\n", "--SC1 thrd", GetDsIrmScThrdMc(V, g_1_scThrd_f, &irm_sc_thrd_mc));
    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-30s: %d\n", "--SC2 thrd", GetDsIrmScThrdMc(V, g_2_scThrd_f, &irm_sc_thrd_mc));
    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-30s: %d\n", "--SC3 thrd", GetDsIrmScThrdMc(V, g_3_scThrd_f, &irm_sc_thrd_mc));
    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-30s: %d\n", "Egress NON-UC resrc mode", p_usw_queue_master[lchip]->egs_resrc_mode[1]);
    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-30s: %d\n", "--Total thrd", GetDsErmMiscThrdMc(V, g_0_totalThrd_f, &erm_misc_thrd_mc));
    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-30s: %d\n", "--SC0 thrd", GetDsErmScThrdMc(V, g_0_scThrd_f, &erm_sc_thrd_mc));
    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-30s: %d\n", "--SC1 thrd", GetDsErmScThrdMc(V, g_1_scThrd_f, &erm_sc_thrd_mc));
    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-30s: %d\n", "--SC2 thrd", GetDsErmScThrdMc(V, g_2_scThrd_f, &erm_sc_thrd_mc));
    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-30s: %d\n", "--SC3 thrd", GetDsErmScThrdMc(V, g_3_scThrd_f, &erm_sc_thrd_mc));

    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "\n");
    return CTC_E_NONE;
}

#endif
